blob: 2a6138b3cbf435b357265ee669bb6ae16393e91a [file] [log] [blame]
Francesc Campoy4d282f82014-02-25 18:28:40 -08001More types: structs, slices, and maps.
2Learn how to define types based on existing ones: this lesson covers structs, arrays, slices, and maps.
3
4The Go Authors
Andrew Gerrand148e7782015-09-28 11:41:35 +10005https://golang.org
Francesc Campoy4d282f82014-02-25 18:28:40 -08006
Andrew Gerrand7f9714c2014-07-17 13:27:17 +10007* Pointers
8
9Go has pointers.
Andrew Gerrandc9941e52016-07-25 13:30:30 +100010A pointer holds the memory address of a value.
Andrew Gerrand7f9714c2014-07-17 13:27:17 +100011
12The type `*T` is a pointer to a `T` value. Its zero value is `nil`.
13
14 var p *int
15
16The `&` operator generates a pointer to its operand.
17
18 i := 42
19 p = &i
20
21The `*` operator denotes the pointer's underlying value.
22
23 fmt.Println(*p) // read i through the pointer p
24 *p = 21 // set i through the pointer p
25
26This is known as "dereferencing" or "indirecting".
27
28Unlike C, Go has no pointer arithmetic.
29
Andrew Gerrandc93c30e2014-07-23 13:47:53 +100030.play moretypes/pointers.go
Andrew Gerrand7f9714c2014-07-17 13:27:17 +100031
Francesc Campoy4d282f82014-02-25 18:28:40 -080032* Structs
33
34A `struct` is a collection of fields.
35
Andrew Gerrandc93c30e2014-07-23 13:47:53 +100036.play moretypes/structs.go
Francesc Campoy4d282f82014-02-25 18:28:40 -080037
38* Struct Fields
39
40Struct fields are accessed using a dot.
41
Andrew Gerrandc93c30e2014-07-23 13:47:53 +100042.play moretypes/struct-fields.go
Francesc Campoy4d282f82014-02-25 18:28:40 -080043
Andrew Gerrand7f9714c2014-07-17 13:27:17 +100044* Pointers to structs
Francesc Campoy4d282f82014-02-25 18:28:40 -080045
Andrew Gerrand7f9714c2014-07-17 13:27:17 +100046Struct fields can be accessed through a struct pointer.
Francesc Campoy4d282f82014-02-25 18:28:40 -080047
Emmanuel Odekea5983ab2016-02-28 21:50:40 -070048To access the field `X` of a struct when we have the struct pointer `p` we could
Andrew Gerrand1e3079b2016-02-26 15:23:49 +110049write `(*p).X`.
50However, that notation is cumbersome, so the language permits us instead to
51write just `p.X`, without the explicit dereference.
Francesc Campoy4d282f82014-02-25 18:28:40 -080052
Andrew Gerrandc93c30e2014-07-23 13:47:53 +100053.play moretypes/struct-pointers.go
Francesc Campoy4d282f82014-02-25 18:28:40 -080054
55* Struct Literals
56
57A struct literal denotes a newly allocated struct value by listing the values of its fields.
58
59You can list just a subset of fields by using the `Name:` syntax. (And the order of named fields is irrelevant.)
60
Andrew Gerrand7f9714c2014-07-17 13:27:17 +100061The special prefix `&` returns a pointer to the struct value.
Francesc Campoy4d282f82014-02-25 18:28:40 -080062
Andrew Gerrandc93c30e2014-07-23 13:47:53 +100063.play moretypes/struct-literals.go
Francesc Campoy4d282f82014-02-25 18:28:40 -080064
Andrew Gerrand41d86d52016-04-01 17:12:52 +110065
Francesc Campoy4d282f82014-02-25 18:28:40 -080066* Arrays
67
68The type `[n]T` is an array of `n` values of type `T`.
69
70The expression
71
72 var a [10]int
73
74declares a variable `a` as an array of ten integers.
75
76An array's length is part of its type, so arrays cannot be resized.
77This seems limiting, but don't worry;
78Go provides a convenient way of working with arrays.
79
Andrew Gerrandc93c30e2014-07-23 13:47:53 +100080.play moretypes/array.go
Francesc Campoy4d282f82014-02-25 18:28:40 -080081
Andrew Gerrand41d86d52016-04-01 17:12:52 +110082
Francesc Campoy4d282f82014-02-25 18:28:40 -080083* Slices
84
Andrew Gerrand41d86d52016-04-01 17:12:52 +110085An array has a fixed size.
86A slice, on the other hand, is a dynamically-sized,
87flexible view into the elements of an array.
88In practice, slices are much more common than arrays.
Francesc Campoy4d282f82014-02-25 18:28:40 -080089
Andrew Gerrand41d86d52016-04-01 17:12:52 +110090The type `[]T` is a slice with elements of type `T`.
Francesc Campoy4d282f82014-02-25 18:28:40 -080091
Rob Phoenixd1a15fa2017-06-06 09:35:16 +010092A slice is formed by specifying two indices, a low and
93high bound, separated by a colon:
Andrew Gerrand41d86d52016-04-01 17:12:52 +110094
Rob Phoenixd1a15fa2017-06-06 09:35:16 +010095 a[low : high]
Andrew Gerrand41d86d52016-04-01 17:12:52 +110096
Rob Phoenixd1a15fa2017-06-06 09:35:16 +010097This selects a half-open range which includes the first
98element, but excludes the last one.
99
100The following expression creates a slice which includes
101elements 1 through 3 of `a`:
102
103 a[1:4]
Katrina Owen9d789a42015-10-07 20:52:49 -0600104
Andrew Gerrandc93c30e2014-07-23 13:47:53 +1000105.play moretypes/slices.go
Francesc Campoy4d282f82014-02-25 18:28:40 -0800106
Katrina Owenb9bdbaa2015-10-19 11:23:28 -0600107
Andrew Gerrand41d86d52016-04-01 17:12:52 +1100108* Slices are like references to arrays
Katrina Owenb9bdbaa2015-10-19 11:23:28 -0600109
Andrew Gerrand41d86d52016-04-01 17:12:52 +1100110A slice does not store any data,
111it just describes a section of an underlying array.
Katrina Owenb9bdbaa2015-10-19 11:23:28 -0600112
Andrew Gerrand41d86d52016-04-01 17:12:52 +1100113Changing the elements of a slice modifies the
114corresponding elements of its underlying array.
Francesc Campoy4d282f82014-02-25 18:28:40 -0800115
Andrew Gerrand41d86d52016-04-01 17:12:52 +1100116Other slices that share the same underlying array will see those changes.
Francesc Campoy4d282f82014-02-25 18:28:40 -0800117
Andrew Gerrand41d86d52016-04-01 17:12:52 +1100118.play moretypes/slices-pointers.go
Francesc Campoy4d282f82014-02-25 18:28:40 -0800119
Francesc Campoy4d282f82014-02-25 18:28:40 -0800120
Andrew Gerrand41d86d52016-04-01 17:12:52 +1100121* Slice literals
Francesc Campoy4d282f82014-02-25 18:28:40 -0800122
Andrew Gerrand41d86d52016-04-01 17:12:52 +1100123A slice literal is like an array literal without the length.
Francesc Campoy4d282f82014-02-25 18:28:40 -0800124
Andrew Gerrand41d86d52016-04-01 17:12:52 +1100125This is an array literal:
Francesc Campoy4d282f82014-02-25 18:28:40 -0800126
Andrew Gerrand41d86d52016-04-01 17:12:52 +1100127 [3]bool{true, true, false}
Francesc Campoy4d282f82014-02-25 18:28:40 -0800128
Andrew Gerrand41d86d52016-04-01 17:12:52 +1100129And this creates the same array as above,
130then builds a slice that references it:
Francesc Campoy4d282f82014-02-25 18:28:40 -0800131
Andrew Gerrand41d86d52016-04-01 17:12:52 +1100132 []bool{true, true, false}
Francesc Campoy4d282f82014-02-25 18:28:40 -0800133
Andrew Gerrand41d86d52016-04-01 17:12:52 +1100134.play moretypes/slice-literals.go
Francesc Campoy4d282f82014-02-25 18:28:40 -0800135
Andrew Gerrand41d86d52016-04-01 17:12:52 +1100136
137* Slice defaults
138
139When slicing, you may omit the high or low bounds to use their defaults instead.
140
141The default is zero for the low bound and the length of the slice for the high bound.
142
143For the array
144
145 var a [10]int
146
147these slice expressions are equivalent:
148
149 a[0:10]
150 a[:10]
151 a[0:]
152 a[:]
153
154.play moretypes/slice-bounds.go
155
156
157* Slice length and capacity
158
159A slice has both a _length_ and a _capacity_.
160
161The length of a slice is the number of elements it contains.
162
163The capacity of a slice is the number of elements in the underlying array,
164counting from the first element in the slice.
165
166The length and capacity of a slice `s` can be obtained using the expressions
167`len(s)` and `cap(s)`.
168
169You can extend a slice's length by re-slicing it,
170provided it has sufficient capacity.
171Try changing one of the slice operations in the example program to extend it
172beyond its capacity and see what happens.
173
174.play moretypes/slice-len-cap.go
175
176
177* Nil slices
178
179The zero value of a slice is `nil`.
180
181A nil slice has a length and capacity of 0
182and has no underlying array.
183
184.play moretypes/nil-slices.go
185
186
187* Creating a slice with make
188
189Slices can be created with the built-in `make` function;
190this is how you create dynamically-sized arrays.
191
192The `make` function allocates a zeroed array
193and returns a slice that refers to that array:
Francesc Campoy4d282f82014-02-25 18:28:40 -0800194
195 a := make([]int, 5) // len(a)=5
196
197To specify a capacity, pass a third argument to `make`:
198
199 b := make([]int, 0, 5) // len(b)=0, cap(b)=5
200
201 b = b[:cap(b)] // len(b)=5, cap(b)=5
202 b = b[1:] // len(b)=4, cap(b)=4
203
Andrew Gerrandc93c30e2014-07-23 13:47:53 +1000204.play moretypes/making-slices.go
Francesc Campoy4d282f82014-02-25 18:28:40 -0800205
Francesc Campoy4d282f82014-02-25 18:28:40 -0800206
Andrew Gerrand41d86d52016-04-01 17:12:52 +1100207* Slices of slices
Francesc Campoy4d282f82014-02-25 18:28:40 -0800208
Andrew Gerrand41d86d52016-04-01 17:12:52 +1100209Slices can contain any type, including other slices.
Francesc Campoy4d282f82014-02-25 18:28:40 -0800210
Andrew Gerrand41d86d52016-04-01 17:12:52 +1100211.play moretypes/slices-of-slice.go
Francesc Campoy57a43f22014-07-14 20:42:45 -0700212
Andrew Gerrand41d86d52016-04-01 17:12:52 +1100213
214* Appending to a slice
Francesc Campoy57a43f22014-07-14 20:42:45 -0700215
216It is common to append new elements to a slice, and so Go provides a built-in
Andrew Gerrand148e7782015-09-28 11:41:35 +1000217`append` function. The [[https://golang.org/pkg/builtin/#append][documentation]]
Francesc Campoy57a43f22014-07-14 20:42:45 -0700218of the built-in package describes `append`.
219
220 func append(s []T, vs ...T) []T
221
222The first parameter `s` of `append` is a slice of type `T`, and the rest are
223`T` values to append to the slice.
224
225The resulting value of `append` is a slice containing all the elements of the
226original slice plus the provided values.
227
228If the backing array of `s` is too small to fit all the given values a bigger
229array will be allocated. The returned slice will point to the newly allocated
230array.
231
Andrew Gerrand148e7782015-09-28 11:41:35 +1000232(To learn more about slices, read the [[https://blog.golang.org/go-slices-usage-and-internals][Slices: usage and internals]] article.)
Francesc Campoy4d282f82014-02-25 18:28:40 -0800233
Andrew Gerrandc93c30e2014-07-23 13:47:53 +1000234.play moretypes/append.go
Francesc Campoy4d282f82014-02-25 18:28:40 -0800235
Andrew Gerrand41d86d52016-04-01 17:12:52 +1100236
Francesc Campoy4d282f82014-02-25 18:28:40 -0800237* Range
238
239The `range` form of the `for` loop iterates over a slice or map.
240
Katrina Owen6cb86ee2015-10-08 11:53:05 -0600241When ranging over a slice, two values are returned for each iteration.
242The first is the index, and the second is a copy of the element at that index.
243
Andrew Gerrandc93c30e2014-07-23 13:47:53 +1000244.play moretypes/range.go
Francesc Campoy4d282f82014-02-25 18:28:40 -0800245
246* Range continued
247
248You can skip the index or value by assigning to `_`.
249
250If you only want the index, drop the ", value" entirely.
251
Andrew Gerrandc93c30e2014-07-23 13:47:53 +1000252.play moretypes/range-continued.go
Francesc Campoy4d282f82014-02-25 18:28:40 -0800253
254* Exercise: Slices
255
256Implement `Pic`. It should return a slice of length `dy`, each element of which is a slice of `dx` 8-bit unsigned integers. When you run the program, it will display your picture, interpreting the integers as grayscale (well, bluescale) values.
257
Andrew Gerrandbb76bbf2015-06-17 08:23:23 +1000258The choice of image is up to you. Interesting functions include `(x+y)/2`, `x*y`, and `x^y`.
Francesc Campoy4d282f82014-02-25 18:28:40 -0800259
260(You need to use a loop to allocate each `[]uint8` inside the `[][]uint8`.)
261
262(Use `uint8(intValue)` to convert between types.)
263
Andrew Gerrandc93c30e2014-07-23 13:47:53 +1000264.play moretypes/exercise-slices.go
Francesc Campoy4d282f82014-02-25 18:28:40 -0800265
266* Maps
267
268A map maps keys to values.
269
Andrew Gerrand3a15bec2016-04-05 11:29:00 +1000270The zero value of a map is `nil`.
Andrew Gerrand9b24cf32016-04-06 15:17:42 +1000271A `nil` map has no keys, nor can keys be added.
Andrew Gerrand30101152016-04-04 11:46:10 +1000272
Andrew Gerrand3a15bec2016-04-05 11:29:00 +1000273The `make` function returns a map of the given type,
274initialized and ready for use.
Francesc Campoy4d282f82014-02-25 18:28:40 -0800275
Andrew Gerrandc93c30e2014-07-23 13:47:53 +1000276.play moretypes/maps.go
Francesc Campoy4d282f82014-02-25 18:28:40 -0800277
278* Map literals
279
280Map literals are like struct literals, but the keys are required.
281
Andrew Gerrandc93c30e2014-07-23 13:47:53 +1000282.play moretypes/map-literals.go
Francesc Campoy4d282f82014-02-25 18:28:40 -0800283
284* Map literals continued
285
286If the top-level type is just a type name, you can omit it from the elements of the literal.
287
Andrew Gerrandc93c30e2014-07-23 13:47:53 +1000288.play moretypes/map-literals-continued.go
Francesc Campoy4d282f82014-02-25 18:28:40 -0800289
290* Mutating Maps
291
292Insert or update an element in map `m`:
293
294 m[key] = elem
295
296Retrieve an element:
297
298 elem = m[key]
299
300Delete an element:
301
302 delete(m, key)
303
304Test that a key is present with a two-value assignment:
305
306 elem, ok = m[key]
307
Katrina Owen25827002015-10-07 23:59:40 -0600308If `key` is in `m`, `ok` is `true`. If not, `ok` is `false`.
Francesc Campoy4d282f82014-02-25 18:28:40 -0800309
Katrina Owen25827002015-10-07 23:59:40 -0600310If `key` is not in the map, then `elem` is the zero value for the map's element type.
Francesc Campoy4d282f82014-02-25 18:28:40 -0800311
Francesc Campoy4d627d92015-07-27 15:26:29 -0700312_Note_: if `elem` or `ok` have not yet been declared you could use a short declaration form:
313
314 elem, ok := m[key]
315
Andrew Gerrandc93c30e2014-07-23 13:47:53 +1000316.play moretypes/mutating-maps.go
Francesc Campoy4d282f82014-02-25 18:28:40 -0800317
318* Exercise: Maps
319
320Implement `WordCount`. It should return a map of the counts of each “word” in the string `s`. The `wc.Test` function runs a test suite against the provided function and prints success or failure.
321
Andrew Gerrand148e7782015-09-28 11:41:35 +1000322You might find [[https://golang.org/pkg/strings/#Fields][strings.Fields]] helpful.
Francesc Campoy4d282f82014-02-25 18:28:40 -0800323
Andrew Gerrandc93c30e2014-07-23 13:47:53 +1000324.play moretypes/exercise-maps.go
Francesc Campoy4d282f82014-02-25 18:28:40 -0800325
326* Function values
327
Katrina Owen500288f2015-10-11 11:39:41 -0600328Functions are values too. They can be passed around just like other values.
329
Katrina Owen64f07e52015-10-12 21:57:01 -0600330Function values may be used as function arguments and return values.
Francesc Campoy4d282f82014-02-25 18:28:40 -0800331
Andrew Gerrandc93c30e2014-07-23 13:47:53 +1000332.play moretypes/function-values.go
Francesc Campoy4d282f82014-02-25 18:28:40 -0800333
334* Function closures
335
336Go functions may be closures. A closure is a function value that references variables from outside its body. The function may access and assign to the referenced variables; in this sense the function is "bound" to the variables.
337
338For example, the `adder` function returns a closure. Each closure is bound to its own `sum` variable.
339
Andrew Gerrandc93c30e2014-07-23 13:47:53 +1000340.play moretypes/function-closures.go
Francesc Campoy4d282f82014-02-25 18:28:40 -0800341
342* Exercise: Fibonacci closure
343
344Let's have some fun with functions.
345
Andrew Gerrande9f50ad2016-01-21 12:54:54 +1100346Implement a `fibonacci` function that returns a function (a closure) that
347returns successive [[https://en.wikipedia.org/wiki/Fibonacci_number][fibonacci numbers]]
348(0, 1, 1, 2, 3, 5, ...).
Francesc Campoy4d282f82014-02-25 18:28:40 -0800349
Andrew Gerrandc93c30e2014-07-23 13:47:53 +1000350.play moretypes/exercise-fibonacci-closure.go
Francesc Campoy4d282f82014-02-25 18:28:40 -0800351
Francesc Campoy4d282f82014-02-25 18:28:40 -0800352* Congratulations!
353
354You finished this lesson!
355
Andrew Gerrand7f9714c2014-07-17 13:27:17 +1000356You can go back to the list of [[/list][modules]] to find what to learn next, or continue with the [[javascript:click('.next-page')][next lesson]].