Struct types, literals and zero values
A struct groups named fields into one type: type User struct { Name string; Age int }. It is Go's answer to a class without the inheritance. You create values with a struct literal, preferably naming each field — User{Name: "Ana", Age: 31} — so the code still compiles and still reads correctly when someone adds a field later.
Fields you leave out get their zero value, and var u User gives a struct where every field is zero. Good Go types are designed so that the zero value is already useful. An anonymous struct — a struct type written inline with no name — is handy for one-off groupings such as table-driven test cases.
package main
import "fmt"
type User struct {
Name string
Age int
Admin bool
Emails []string
}
func main() {
ana := User{Name: "Ana", Age: 31} // named fields: order-free
fmt.Println(ana.Name, ana.Age, ana.Admin, ana.Emails == nil)
var nobody User // every field is its zero value
fmt.Printf("%+v\n", nobody)
ana.Age++ // fields are read and written with a dot
ana.Emails = append(ana.Emails, "[email protected]")
fmt.Printf("%+v\n", ana)
point := struct{ X, Y int }{3, 4} // anonymous struct
fmt.Println(point.X*point.X + point.Y*point.Y)
tests := []struct {
in string
want int
}{
{"go", 2},
{"gopher", 6},
}
for _, tc := range tests {
fmt.Println(tc.in, len(tc.in) == tc.want)
}
}Ana 31 false true
{Name: Age:0 Admin:false Emails:[]}
{Name:Ana Age:32 Admin:false Emails:[[email protected]]}
25
go true
gopher trueAdd a Country string field to User. Which lines of main need to change? (None — that is the benefit of named-field literals.)
unknown field Nmae in struct literal of type User
package main
import "fmt"
type User struct {
Name string
Age int
}
func main() {
u := User{Nmae: "Ana", Age: 31}
fmt.Println(u)
}# command-line-arguments
./main.go:11:12: unknown field Nmae in struct literal of type UserA struct's fields are fixed at compile time, so a typo in a field name is caught immediately — unlike a map key or a JavaScript object property, which would silently create a new entry.
Correct the field name. An editor running gopls offers field-name completion inside struct literals.
package main
import "fmt"
type User struct {
Name string
Age int
}
func main() {
u := User{Name: "Ana", Age: 31}
fmt.Println(u)
}Name) is exported — visible to other packages, and to packages like encoding/json. A lowercase field (name) is private to the package. The same rule applies to the type name itself.