Declare Arrays and Slices in Go

Jeff Roberts
InstructorJeff Roberts
Share this video with your friends

Social Share Links

Send Tweet
Published 5 years ago
Updated 4 years ago

There are numerous ways that you can declare and create arrays and slices in Go. This lesson will show you several and I talk about the advantages and disadvantages of one over another. After watching, you will better understand all of the possible ways you can declare/create as well as the idiomatic way.

These include:

  • var
  • the built-in function new
  • the built-in function make
  • Array and Slice literals

While it is not the main intent of this lesson, I do touch on some of the differences between slices and arrays.

Checkout the code in my github repo.

Instructor: [00:00] declaring slices and arrays. Let's start by using var. Var in all cases declares a variable of a specific type and generally, always creates a variable of its zero type. We'll see what that means here in a second.

[00:22] What I'm doing is I'm logging out the type of the variable I've created, the length, the capacity, the variable value itself and whether it's nil. Let's ran this and let's see what happens here.

[00:38] You can see that I created a variable called A. It's a slice of ints, it has a length of zero and a capacity of zero and it's initialized, there's nothing in it, but it says it's nil. That's because the zero value of a slice is always nil.

[00:57] How did I declare A? What can I do with it? Since it's a slice, can I do this? This actually causes a panic and it's because A is actually nil, so you can't assign anything to the zero of element of A. Interestingly, here we do a length of A and a cap of A and those two built-in functions have nil handling cases. Since A is nil, the length here of A reports zero and the capacity reports zero.

[01:44] Next way we can declare a slice, actually, is using the built-in function new. What new does in all cases is it creates a pointer to the zero value of the type that it's creating. Here, B is going to be a pointer to a slice of ints. Let's run this, see what happens. B is a pointer to a slice of ints. It has a length of zero, capacity is zero and it's actually a pointer to a slice, but it's not nil in this case.

[02:22] Next stop, we're going to declare a slice variable C using the built-in function make. Make is a special Golang function, which is used exclusively for slices, maps and channels. Here, we're using it to declare a slice. That's because make does some extra work for those three types because extra work is required to actually create one of this.

[02:51] In this case, make accepts the type that it wants to make, the initial length and optionally, the capacity. In this case, we're leaving out the capacity so it defaults to the length.

[03:08] Let's see what happens here when I run this. C in this case is just like in the other cases a type of slice of ints. It has an initial length of five, a capacity of five and you can see now that it has an initial value as well. Not the zero value, but it's actually a slice of five ints all initialized to zero and it's not nil.

[03:38] Make is a very common way of declaring and creating a slice and you use that frequently in your code. Here's an alternate form of make. In the previous example, we created C, a slice of ints with an initial length of five and we left out the capacity. Here' we're specifying the capacity.

[03:58] In the previous example, it defaulted to the length, but we want something different here. This is going to...If we ran this, create D, which is a slice of ints, has an initial length of five, a capacity of 100 and you'll see that it's initialized the same and it's also not nil.

[04:18] Let's take a look now using the same mechanisms to declare arrays. Here, we're declaring E to be a fixed-sized array of three ints. This is different than a slice. Arrays are fixed elements, they cannot grow like a slice can.

[04:43] In this case, I'm going to log out the same thing, but the zero value of an array is an array, a usable array. Let's run this and we'll see. Actually, because I'm trying to compare E to nil, the compiler says E can never be nil because the type is an array and an array can never be nil.

[05:08] In this case, I can't actually compare E to nil, so let's just make a copy of this and comment this out so that we have reference to that. Let's get rid of the nil comparison here and not print it. Let's run it again and let's look at E. E says this is a type of array that has a length of three and a capacity of three and we can see that it got initialized to an empty array with zeros in all three elements.

[05:47] Just like with slices, we can use the new built-in function to declare and create a pointer to an array of ints. Again, this is not something you'll do very frequently if ever, but it can be done. Let's run this and see what happens.

[06:05] F is a pointer to an array of ints, length of three, capacity of three. We can see that it's a pointer to that and it is in fact not nil. What I've shown you so far is how to declare variables, either slices or arrays using var, new and make.

[06:27] In this case, I want to show you how to both declare and initialize using literals. In this case, G is declared as a slice of ints and I'm initializing it as part of this literal syntax to say initialize it to ints one, three and six. Let's run this and see what happens.

[06:52] G is a slice of int, has a length of three and capacity of three and you can see that since we use literal syntax instead of initializing it to three zeros, we provided the values that we wanted to initialize it with, one, three and six in this case. Because we initialized it with a literal, it's no longer a zero value slice and it is not nil.

[07:17] Next example, we're using literal syntax again to declare and initialize a slice of int, except we're not specifying any values. What's that actually going to do is it's going create a slice, it won't be nil as we can see here.

[07:36] H is a slice of int, but it has a length of zero and a capacity of zero because we didn't actually provide any values in the literal up here and it is not false. We can use this slice as an argument to the append function, but since it's length and capacity are zero, we can't do something like this. Oops, equals one or something like that. This would in fact fail and it does.

[08:11] Let's take a look at a slightly more complicated example. Here, I'm declaring I which is a slice of champions and I'm using literal syntax to initialize it to two different champions. What is this champion?

[08:28] Let's take a look over here in my other data.go file and I declare a strapped called champion. This is in reference to something I like to play, it's a game I like to play called Teamfight Tactics. The champion is our characters in the game. They have a name, they have a slice of classes, a slice of origins and a gold cost.

[08:53] In here, back in this example I'm using a literal to create Evelyn, who is an assassin and a demon, cost three gold and Vi who is a Brawler Hextech and cost three. Let's run this and see what I get.

[09:11] Here we have I, which is a champion, a slice of champions. It has a length and a capacity of two because my literal had two elements in it. We can see that I logged out the contents of that slice and it is in fact not nil, which it shouldn't be because I used literal syntax to initialize it.

[09:34] We can also use literals with arrays, not just slices. Here I declared J, which is a fixed length array, three elements and I used literal syntax just like in the slice scenario to initialize the array to values of one, three and five. We can see here when I log this out that J is a fixed length array of ints. It has a length and a capacity of three. Its initial value is what I specified in the literal.

[10:07] Last thing I want to show you is this special way of using a literal with an array without specifying the length. Instead of the length, this little syntax tells the compiler, "You figure out the length based upon the literal."

[10:23] In this case, let's just add another one here. The compiler is going to determine, as we can see when we run it, that K is of type, a fixed-length array of four elements. It has a length and a capacity of four, and it initializes it to the value that we specified.

[10:47] We can see all these different ways of declaring and initializing slices and arrays.