package main
import (
"fmt"
)
type Animal struct {
Name string
Age int
Species string
Weight float64
}
func main() {
var vet [4]Animal
vet[0] = Animal{"Doug", 5, "Dog", 25.0}
vet[1] = Animal{"Catherine", 1, "Cat", 2}
vet[2] = Animal{"Gary", 1, "Goldfish", 0.1}
vet[3] = Animal{"Percy", 10, "Python", 50.0}
for i, animal := range vet {
fmt.Println("animal at", i, "is", animal)
}
// get a slice of the middle 2, X:Y is not inclusive
middle := vet[1:3]
fmt.Println("middle has", len(middle), "elements")
// if you don't need i replace with _
for _, animal := range middle {
fmt.Println("middle is", animal)
}
// adds one more to this slice !!footgun
middle = append(middle, Animal{"Jack", 1, "Jaybird", 0.1})
for i, animal := range middle {
fmt.Println("middle", i, "is", animal)
}
// changing that slice changes the original vet !!footgun
middle[0].Name = "CHANGED"
fmt.Println("the one I changed", middle[0])
fmt.Println("original is", vet[1])
// copy is good for small slices of big arrays
// why: small slices still reference the big array
// so the GC retains: !!footgun memory leaking on slices
front := make([]Animal, 2)
copy(front, vet[0:2])
front[0].Name = "WONT CHANGE"
fmt.Println("front one", front[0])
fmt.Println("original unchanged", vet[0])
// using ... to copy
numbers := make([]int, 0, 4)
numbers = append(numbers, 1, 2, 3, 4)
var new_numbers []int
new_numbers = append(new_numbers, numbers...)
new_numbers[0] = 100
fmt.Println("numbers:", numbers)
fmt.Println("new_numbers:", new_numbers)
// concat with append
numbers = append(numbers, new_numbers...)
fmt.Println("concat numbers:", numbers)
}