Structs & Methods

📋 Jump to Takeaways

Go doesn't have classes. No inheritance, no constructors, no this. Instead, you get structs and methods, and somehow that's all you need. Docker, Kubernetes, and Terraform are all built with just structs, methods, and interfaces. No class hierarchies in sight.

Defining Structs

A struct groups related fields together.

type User struct {
    Name string
    Age  int
}

Creating Instances

There are several ways to create a struct.

// Struct literal — set fields inline
u1 := User{Name: "Alice", Age: 30}

// Zero value — fields default to their zero values
var u2 User
fmt.Println(u2.Name) // "" (empty string)
fmt.Println(u2.Age)  // 0

// Pointer with fields — most common way to get a pointer
u3 := &User{Name: "Bob", Age: 25}

new()

new(T) allocates a zero-value T and returns a pointer to it. It works with any type, not just structs.

p := new(int)       // *int pointing to 0
fmt.Println(*p)     // 0

u := new(User)      // *User with all fields at zero values
fmt.Println(u.Name) // ""

In practice, &User{...} is preferred for structs because you can set fields inline. new is more useful when you just need a pointer to a zero value, especially with basic types like int or bool where you can't write &0.

Accessing Fields

Use dot notation to read and write fields.

u := User{Name: "Alice", Age: 30}
fmt.Println(u.Name) // Alice
u.Age = 31
fmt.Println(u.Age) // 31

Exported vs Unexported Fields

The same uppercase/lowercase visibility rule from Getting Started applies to struct fields.

type Config struct {
    Host    string // exported — accessible from other packages
    port    int    // unexported — only accessible within this package
}

Methods with Value Receivers

A method is a function with a receiver. Value receivers get a copy of the struct.

func (u User) Greet() string {
    return "Hi, I'm " + u.Name
}

u := User{Name: "Alice"}
fmt.Println(u.Greet()) // Hi, I'm Alice

Pointer Receivers

Pointer receivers can modify the original struct. Use them when you need to mutate state or avoid copying large structs.

func (u *User) SetName(name string) {
    u.Name = name
}

u := User{Name: "Alice"}
u.SetName("Bob")
fmt.Println(u.Name) // Bob

With a value receiver, changes don't persist:

func (u User) SetAge(age int) {
    u.Age = age // modifies the copy, not the original
}

u := User{Age: 30}
u.SetAge(99)
fmt.Println(u.Age) // 30 — unchanged

Pointers

& gets the address of a variable. * dereferences a pointer to access the value.

x := 42
p := &x       // p is a pointer to x
fmt.Println(*p) // 42
*p = 100
fmt.Println(x) // 100 — x changed through the pointer

This is why pointer receivers can modify the struct. They receive the address, not a copy.

Struct Embedding

Go uses composition instead of inheritance. Embed a struct to promote its fields and methods.

type Animal struct {
    Name string
}

func (a Animal) Speak() string {
    return a.Name + " speaks"
}

type Dog struct {
    Animal // embedded
    Breed  string
}

d := Dog{Animal: Animal{Name: "Rex"}, Breed: "Lab"}
fmt.Println(d.Name)    // Rex — promoted field
fmt.Println(d.Speak()) // Rex speaks — promoted method

Struct Tags

Tags attach metadata to fields. The json tag controls JSON encoding/decoding.

type User struct {
    Name  string `json:"name"`
    Email string `json:"email,omitempty"`
    Age   int    `json:"-"` // excluded from JSON
}

u := User{Name: "Alice", Age: 30}
data, _ := json.Marshal(u)
fmt.Println(string(data)) // {"name":"Alice"}

Key Takeaways

  • Structs group related data; create them with literals, new(), or zero values
  • Uppercase fields are exported, lowercase are unexported
  • Value receivers get a copy; pointer receivers can modify the original
  • & takes an address, * dereferences — pointer receivers need this to mutate
  • Embedding promotes fields and methods for composition
  • Struct tags control serialization behavior like JSON field names

📝 Ready to test your knowledge?

Answer the quiz below to mark this lesson complete.

© 2026 ByteLearn.dev. Free courses for developers. · Privacy