Structs
Structs
A struct groups related fields under one named type — the closest thing Go has to a class, minus inheritance:
type Person struct {
Name string
Age int
}
p := Person{Name: "Haleh", Age: 34}
fmt.Println(p.Name) // Haleh
p.Age = 35 // structs are mutable by defaultCapitalized field names (Name, Age) are exported outside the package, same rule as everywhere else in Go — lowercase them (name, age) if a field should stay package-private.
Structs are values, not references
This is the detail most likely to surprise you coming from Python or JavaScript, where assigning or passing an object just copies a reference to the same underlying data. In Go, assigning a struct — or passing one to a function — copies the whole thing:
p1 := Person{Name: "Ada", Age: 36}
p2 := p1
p2.Name = "Grace"
fmt.Println(p1.Name) // Ada — unchanged
fmt.Println(p2.Name) // Gracep2 is an independent copy; modifying it never touches p1. This is exactly the kind of behavior that will bite you once — pass a struct to a function expecting to mutate the caller's copy, and watch the caller's copy stay unchanged — before it clicks. The fix, once you need it, is a pointer to the struct instead of the struct itself, which you'll see properly in the next module.
Nested structs
type Address struct {
City string
Country string
}
type Person struct {
Name string
Age int
Address Address
}
p := Person{
Name: "Haleh",
Age: 34,
Address: Address{
City: "Toronto",
Country: "Canada",
},
}
fmt.Println(p.Address.City) // TorontoComposing small structs like this — rather than one large flat one — is the idiomatic way to model related-but-distinct groups of fields, and it sets up naturally for the methods and interfaces you'll meet next.