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

Leave a Comment