A Tour of Go - Basics: More types: structs, slices, and maps. Flashcards
Does Go have pointers?
Go has pointers. A pointer holds the memory address of a value.
The type *T
is a pointer to a T
value. Its zero value is nil.
var p *int
What is the address operator?
The & generates a pointer to it’s operand
i := 42 p := &i
What is the derefence operator?
The * operator denotes the pointer’s underlying value.
fmt.Println(*p) *p = 21
Does Go support pointer arithmetic like ‘C’?
No.
How is a struct declared in Go?
A struct is a collection of fields
type Vertex struct { X int Y int }
How are struct fields accessed?
Using a dot
var v Vertex v.X = 1 x.Y = 5
How are fields accessed with a struct pointer?
To access the field X of a struct when we have the struct pointer p we could write (*p).X. However, that notation is cumbersome, so the language permits us instead to write just p.X, without the explicit dereference.
v := &Vertex{} (*v).X = 1 v.Y = 5
What are struct literals?
A struct literal denotes a newly allocated struct value by listing the values of its fields.
You can list just a subset of fields by using the Name: syntax. (And the order of named fields is irrelevant.)
The special prefix &
returns a pointer to the struct value.
v1 = Vertex{1, 2} // has type Vertex v2 = Vertex{X: 1} // Y:0 is implicit v3 = Vertex{} // X:0 and Y:0 p = &Vertex{1, 2} // has type *Vertex
How are arrays declared?
The type [n]T is an array of n values of type T.
var a [10]int
An array’s length is ….
An array’s length is part of its type, so arrays cannot be resized.
What is a slice?
An array has a fixed size. A slice, on the other hand, is a dynamically-sized, flexible view into the elements of an array.
How is a slice declared?
The type []T
is a slice with elements of type T
.
primes := [6]int{2, 3, 5, 7, 11, 13} var s []int = primes[1:4]
What is a slice literal?
A slice literal is like an array literal without the length.
r := []bool{true, false, true}
This creates an array then builds a slice that references it.
What are the defaults for a slice lower bound?
zero
What is the default for a slice upper bound?
The length of the array - len(s)
What is the length of a slice?
The length of a slice is the number of elements it contains.
len(s)
What is the capacity of the slice?
The capacity of a slice is the number of elements in the underlying array, counting from the first element in the slice.
cap(s)
Whats the zero value of a slice?
The zero value of a slice is nil.
A nil slice has a length and capacity of 0 and has no underlying array.
In Go, how can you create a dynamically-sized array?
Use the built-in make
function. The make
function allocates a zeroed array and returns a slice that refers to that array:
a := make([]int, 5) // len(a)=5
What is the 3rd argument to the built-in `make function?
To specify a capacity, pass a third argument to make
:
b := make([]int, 0, 5) // len(b)=0, cap(b)=5
What types can a slice contain?
Any, including other slices.
// Create a tic-tac-toe board. board := [][]string{ []string{"_", "_", "_"}, []string{"_", "_", "_"}, []string{"_", "_", "_"}, }
How can you append elements to a slice?
Go provides a built-in function append
. The first parameter s
of append
is a type T
, and the rest are T
values to append to the slice.
If the backing array of s is too small to fit all the given values a bigger array will be allocated. The returned slice will point to the newly allocated array.
How do you iterate over a slice?
The range
form of the for
loop iterates over a slice.
When ranging over a slice, two values are returned for each iteration. The first is the index, and the second is a copy of the element at that index.
for i, v := range s { fmt.Printf("s[%d] = %d\n", i, v) }
With a range
for loop can you skip the index or value?
You can skip the index or value by assigning to _.
for i, _ := range pow for _, value := range pow
If you only want the index, you can omit the second variable.
for i := range pow
In Go, what is a map?
A map maps keys to values.
The zero value of a map is nil. A nil map has no keys, nor can keys be added.
The make function returns a map of a given type initialised and ready for use.
var m map[string]string m = make(map[string]string)
What is a map literal?
A map literals are like struct literals, but the keys are required.
var m = map[string]Vertex{ "Bell Labs": Vertex{ 40.68433, -74.39967, }, "Google": Vertex{ 37.42202, -122.08408, }, }
What can you omit from a map literal?
If the top-level type is just a type name, you can omit it from the elements of the literal.
var m = map[string]Vertex{ "Bell Labs": {40.68433, -74.39967}, "Google": { 37.42202, -122.08408}, }
How do you insert or update a map element?
m[key] = elem
How do you retrieve a map element?
elem = m[key]
How do you delete a map element
delete(m, key)
How do you test a map key is present?
A two-value assignment can be used:
elem, ok = m[key]
If key
is in m
, ok is true. if not ok
is `false.
if key
is not in the map, then elem
is the zero value for the map’s element type.
In Go, are functions values?
Yes. They can be passed around just like other values.
Function values may be used as function arguments and return values.
func compute(fn func(float64, float64) float64) float64 { return fn(3, 4) } func main() { hypot := func(x, y float64) float64 { return math.Sqrt(x*x + y*y) } fmt.Println(hypot(5, 12)) fmt.Println(compute(hypot)) fmt.Println(compute(math.Pow)) }
What is a function closure?
A closure is a function value that references variables from outside it’s body. The function may access and assign to the referenced variables; in this sense the function is “bound” to the variables.
Give an example of a closure?
func adder() func(int) int { sum := 0 return func(x int) int { sum += x return sum } } func main() { pos, neg := adder(), adder() for i := 0; i < 10; i++ { fmt.Println( pos(i), neg(-2*i), ) } }
Complete the fibonacci closure:
func fibonacci() func() int { } func main() { f := fibonacci() for i := 0; i < 10; i++ { fmt.Println(f()) } }
func fibonacci() func() int { a, b := 0, 1 return func() int { f := a a, b = a+b, f return f } }