Structs
fmtA struct is a typed collection of fields. Structs group data together to form records.
package main
import "fmt"This person struct type has name and age fields.
type person struct {
name string
age int
}newPerson constructs a new person. Go has no constructors; a function named newX is the convention.
func newPerson(name string) *person {It is safe to return a pointer to a local variable: it lives on as long as something refers to it.
p := person{name: name}
p.age = 42
return &p
}
func main() {This syntax creates a new struct.
fmt.Println(person{"Bob", 20})You can name the fields when initializing a struct.
fmt.Println(person{name: "Alice", age: 30})Omitted fields get their zero value.
fmt.Println(person{name: "Fred"})An & prefix yields a pointer to the struct.
fmt.Println(&person{name: "Ann", age: 40})It's idiomatic to wrap creation in a constructor function.
fmt.Println(newPerson("Jon"))Access fields with a dot.
s := person{name: "Sean", age: 50}
fmt.Println(s.name)Dots work with pointers too; they are dereferenced automatically.
sp := &s
fmt.Println(sp.age)Structs are mutable.
sp.age = 51
fmt.Println(sp.age)Assigning a struct copies it, and == compares the fields.
t := s
t.name = "Tom"
fmt.Println(s.name, t.name, s == person{"Sean", 51})%+v prints field names, %#v prints Go syntax.
fmt.Printf("%+v\n%#v\n", s, s)An anonymous struct type is useful for one-off values, such as table-driven tests.
dog := struct {
name string
isGood bool
}{
"Rex",
true,
}
fmt.Println(dog)A struct can be compared with == when every field can. A slice field makes the whole struct incomparable.
// fmt.Println(struct{ xs []int }{} == struct{ xs []int }{})
// error: invalid operation: struct{xs []int}{} == struct{xs []int}{} (struct containing []int cannot be compared)
}$ go run ./19_structs {Bob 20} {Alice 30} {Fred 0} &{Ann 40} &{Jon 42} Sean 50 51 Sean Tom true {name:Sean age:51} main.person{name:"Sean", age:51} {Rex true}