Structs and Data Modeling
Overview
Structs are Go’s primary mechanism for creating custom composite types. They group related fields together.
Defining Structs
type Person struct {
Name string
Age int
Email string
Active bool
}Creating Instances
// Zero value
var p Person // All fields get zero values
// Literal (named fields - preferred)
p := Person{
Name: "Alice",
Age: 30,
Email: "alice@example.com",
}
// Literal (positional - fragile)
p := Person{"Alice", 30, "alice@example.com", true}
// Using new
p := new(Person) // *Person with zero values
// Expression-based new (Go 1.26+)
p := new(Person{Name: "Alice"}) // *Person initialized with valuesEmbedded fields (composition)
Employee
|-- Person
| |-- Name
| |-- Age
|-- Address
| |-- City
|-- Title
Accessing Fields
p.Name = "Bob"
fmt.Println(p.Age)
// Pointer access (automatic dereference)
ptr := &p
ptr.Name = "Carol" // Same as (*ptr).NameAnonymous Structs
point := struct {
X, Y int
}{10, 20}
// Useful for one-off data
data := struct {
ID int
Value string
}{1, "test"}Embedding (Composition)
type Address struct {
Street string
City string
}
type Employee struct {
Person // Embedded
Address // Embedded
Title string
}
e := Employee{
Person: Person{Name: "Alice", Age: 30},
Address: Address{City: "NYC"},
Title: "Engineer",
}
// Promoted fields
e.Name // Same as e.Person.Name
e.City // Same as e.Address.CityComparison
Structs are comparable if all fields are comparable:
p1 := Person{Name: "Alice"}
p2 := Person{Name: "Alice"}
p1 == p2 // trueConstructors
Go uses factory functions:
func NewPerson(name string, age int) *Person {
return &Person{
Name: name,
Age: age,
Active: true, // Default
}
}
func NewPersonWithDefaults() *Person {
return &Person{
Active: true,
}
}Summary
| Pattern | Usage |
|---|---|
| Define | type Name struct { fields } |
| Create | Name{Field: value} |
| Embed | Include type name without field name |
| Tags | Field Type \key:“value”`| | Constructor |func NewType() *Type` |