Go Structs
A struct groups related fields together under one name. It is Go's way of creating custom data types. Where a variable holds one piece of data and a map holds key-value pairs of the same type, a struct holds multiple named fields that can each have a different type.
Defining and Using a Struct
package main
import "fmt"
type Person struct {
Name string
Age int
City string
}
func main() {
p := Person{
Name: "Alice",
Age: 30,
City: "Mumbai",
}
fmt.Println(p.Name) // Alice
fmt.Println(p.Age) // 30
fmt.Println(p.City) // Mumbai
}
Struct Diagram
type Person struct
┌──────────────────────┐
│ Name │ "Alice" │ ← string field
│ Age │ 30 │ ← int field
│ City │ "Mumbai" │ ← string field
└──────────────────────┘
Access with dot notation:
p.Name → "Alice"
p.Age → 30
Struct with Default Zero Values
Declaring a struct without values fills all fields with their zero values.
package main
import "fmt"
type Product struct {
Name string
Price float64
Stock int
}
func main() {
var item Product
fmt.Println(item) // { 0 0}
fmt.Println(item.Name) // ""
fmt.Println(item.Price) // 0
fmt.Println(item.Stock) // 0
}
Updating Struct Fields
package main
import "fmt"
type Car struct {
Brand string
Speed int
}
func main() {
c := Car{Brand: "Toyota", Speed: 120}
c.Speed = 160
fmt.Println(c.Brand, c.Speed) // Toyota 160
}
Struct as Function Parameter
Structs passed to functions are copied by default. The original does not change inside the function.
package main
import "fmt"
type Rectangle struct {
Width float64
Height float64
}
func area(r Rectangle) float64 {
return r.Width * r.Height
}
func main() {
rect := Rectangle{Width: 10, Height: 5}
fmt.Println("Area:", area(rect)) // Area: 50
}
Nested Structs
A struct can contain another struct as a field.
package main
import "fmt"
type Address struct {
City string
State string
}
type Employee struct {
Name string
Salary int
Address Address
}
func main() {
emp := Employee{
Name: "Bob",
Salary: 50000,
Address: Address{
City: "Bangalore",
State: "Karnataka",
},
}
fmt.Println(emp.Name) // Bob
fmt.Println(emp.Address.City) // Bangalore
}
Anonymous Struct
A struct can be defined inline without a type name. Useful for one-time use cases.
package main
import "fmt"
func main() {
config := struct {
Host string
Port int
}{
Host: "localhost",
Port: 8080,
}
fmt.Println(config.Host, config.Port) // localhost 8080
}
Slice of Structs
package main
import "fmt"
type Student struct {
Name string
Grade int
}
func main() {
students := []Student{
{Name: "Alice", Grade: 90},
{Name: "Bob", Grade: 85},
{Name: "Carol", Grade: 92},
}
for _, s := range students {
fmt.Printf("%s: %d\n", s.Name, s.Grade)
}
}
Output:
Alice: 90
Bob: 85
Carol: 92
Key Points
- Structs group multiple named fields with different types into one custom type
- Fields are accessed with dot notation:
variable.FieldName - Structs are value types — passing to a function creates a copy
- Structs can be nested inside other structs
- Slices of structs are the standard way to represent a list of records
