Structs in Go: A Practical Guide with Examples
A struct groups related fields into a single Go type. Structs are the standard way to model domain entities, configuration, request data, records, and many other compound values.
Define a Struct
type Person struct {
Name string
Age int
Address string
}
p := Person{Name: "Alice", Age: 30, Address: "123 Main St"}
fmt.Println(p.Name, p.Age, p.Address)Using field names in composite literals is usually clearer and more resilient than relying on field order.
Create Struct Values
Common forms include:
p1 := Person{Name: "Alice", Age: 30}
p2 := new(Person) // *Person with zero-value fields
p3 := Person{} // Person with zero-value fieldsnew(Person) returns a pointer. Most Go code uses a struct literal directly unless a pointer is specifically useful.
Access and Modify Fields
p.Age = 31
fmt.Println(p.Age)Add Methods
Methods associate behavior with a type:
func (p Person) Display() {
fmt.Printf("%s, %d, %s\n", p.Name, p.Age, p.Address)
}
func (p *Person) HaveBirthday() {
p.Age++
}
p.Display()
p.HaveBirthday()
p.Display()Use a pointer receiver when the method must modify the receiver. Receiver choice can also matter for method sets and interface satisfaction.
Pass Structs to Functions
Go passes arguments by value. Passing a struct directly copies the struct value:
func rename(p Person) {
p.Name = "Changed"
}Passing a pointer lets the function modify the caller’s struct:
func celebrateBirthday(p *Person) {
p.Age++
}
celebrateBirthday(&p)Do not choose pointers solely from habit. Small immutable values are often simpler to pass by value.
Nested Structs
Structs can contain other structs:
type Address struct {
Street string
City string
Zip string
}
type Person struct {
Name string
Age int
Address Address
}
p := Person{
Name: "Alice",
Age: 30,
Address: Address{
Street: "123 Main St",
City: "Wonderland",
Zip: "12345",
},
}
fmt.Printf("%s lives at %s, %s, %s.\n",
p.Name, p.Address.Street, p.Address.City, p.Address.Zip)Struct Tags
Tags add metadata used by packages such as encoding/json:
type User struct {
ID int `json:"id"`
Email string `json:"email"`
}Tags are strings interpreted by libraries; Go itself does not enforce their meaning.
Conclusion
Structs are the foundation of data modeling in Go. Define clear fields, use methods when behavior belongs to the type, choose value or pointer semantics intentionally, and compose larger models from smaller structs when it improves clarity.