# Go - Maps, Functions cont., Structs, and Receivers

###### Contemporary Programming Languages - CS2001 - 7 November 2017

``````package main
import "fmt"
func f(x []int) {
x[0] = 10
}
func g(x []int) {
x = append(x, 10)
}
func main() {
s := []int {1, 2, 3, 4, 5}
f(s)
t := []int {1, 2, 3, 4, 5}
g(t)
fmt.Println(s, t)
}
``````
``````package main
import "fmt"
func f() (x int) {
defer func() {
x = 1
}()
defer func() {
x = 2
}()
defer func() {
x = 3
}()
x = 4
return
}
func main() {
fmt.Println(f())
}
``````

### Maps

#### Working with Maps

``````counts := map[string]int {"dogs": 3, "cats": 0}
counts["dinosaurs"] = 10
fmt.Println(counts["dinosaurs"]) // 10
delete(counts, "dinosaurs")
``````

`counts["giraffe"] // zero value for missing keys` How can you tell if you had 0 giraffes or no value? `val, ok := counts["giraffe"] // ok is true if key exists, false if not in map`

``````if val, ok := counts["giraffe"]; ok {
// case that the key exists
} else {
// case that the key doesn't exist
}
``````

### Functions Cont.

• Arguments are passed by value
• Need to change a value in the calling function? Use a pointer.
• There’s no pass by reference
``````package main
import "fmt"
func f(x int) {
x++
}
func g(x *int) {
(*x)++
}
func main() {
var a, b int
f(a)
g(&b)
fmt.Println(a, b)
}
``````

#### Function Values

• Functions are values, too.
• They can be passed to functions
• They can be returned from functions
``````package main
import(
"fmt"
"math"
)
// fn is var name, then type of variable is func(), then return of passed function
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)) // 13
fmt.Println(compute(hypot)) // 5
fmt.Println(mat.Pow) // 81
}
``````

#### Function Closures

• Go functions can have closures
• A function can still reference variables from an outer function’s scope, even after the outer function has returned
``````package main
import "fmt"
sum := 0
return func(x int) int {
sum += x
return sum
}
}
func main() {
for i := 0; i < 10; i++ {
fmt.Println(a(i))
}
}
// 0 1 3 6 10 15 21 28
``````

### Structs

• A collection of fields
``````type Pony struct {
Name           string
Height, Weight float64
FavoriteFoods  []string
}
func main() {
dave := Pony {"Dave", 3.2, 100, []string {"pie"}}
alice := Pony {Name: "Alice", Weight: 100, Height: 3.2, FavoriteFoods: []string {"Kale"}}
carol := Pony {Name: "carol"}
e := Pony {}
p := &Pony {} // *Pony
p2 := new(Pony)

dave.Name = "Davey"
}
// Implicit dereference
p.Name = "Peter"

fmt.Println(dave) // {Davey 3.2 100 [pie]}
``````

### Exporting

• Items (funcs, structs, struct fields, constants, variables, etc.) that start with a capitol letter are exported from a package
• If you import a package, you can only access exported items
• We’ll talk about packages more later.

### Methods

• Go does not have classes
• But, you can define methods on types (including structs)
``````func(p Pony) PrintFavorites() {
fmt.Println(p.Name, "likes", strings.Join(p.FavoriteFoods, ","))
}
func main() {
dave := Pony {"Dave", 3.2, 100, []string {"carrot", "broccoli"}}
dave.PrintFavorites() // dave likes carrot, broccoli
}
``````

#### Value Recievers

• Methods w/ value receivers operate on copies of the original value
• Changing attributes of the received value does nothing to the original

• Methods can modify the value to which the reveiver points
• More common than value receivers
``````func(p *Pony) AddFavorite(f string) {
p.FavoriteFoods = append(p.FavoriteFoods, f)
}
func main() {
dave := <dave details>