Menu
Coddy logo textTech

Pointers to Structs

Part of the Object Oriented Programming section of Coddy's GO journey — lesson 20 of 107.

When working with structs, you'll often use pointers to avoid copying large data structures and to modify the original struct. A pointer to a struct holds the memory address of that struct instance.

You can create a struct pointer using the & operator on an existing struct, or by using the address operator directly with a struct literal.

type Person struct {
    Name string
    Age  int
}

p := Person{Name: "Alice", Age: 30}
ptr := &p  // pointer to existing struct

// Or create directly
ptr2 := &Person{Name: "Bob", Age: 25}

Go provides a convenient shortcut when accessing struct fields through a pointer. Instead of writing (*ptr).Name, you can simply write ptr.Name. Go automatically dereferences the pointer for you.

ptr := &Person{Name: "Alice", Age: 30}

// Both work identically
fmt.Println((*ptr).Name)  // explicit dereference
fmt.Println(ptr.Name)     // automatic dereference

This automatic dereferencing also applies when modifying fields. Changes through the pointer affect the original struct.

p := Person{Name: "Alice", Age: 30}
ptr := &p

ptr.Age = 31           // modifies original
fmt.Println(p.Age)     // 31

Struct pointers are essential in Go's OOP patterns. They enable methods to modify receiver state, allow efficient passing of large structs to functions, and form the foundation for building linked data structures like trees and lists.

challenge icon

Challenge

Easy

Let's build a bank account system that demonstrates how struct pointers allow you to modify the original data efficiently. You'll create an account that can be updated through pointer operations.

You'll organize your code across two files:

  • account.go: Define a BankAccount struct with Owner (string), Balance (float64), and AccountNumber (string) fields. Create a function called NewAccount that takes an owner name and account number as parameters and returns a pointer to a new BankAccount with a starting balance of 0. Also create a Deposit function that takes a *BankAccount pointer and an amount, then adds that amount to the account's balance through the pointer.
  • main.go: Read account information from input, create an account using your constructor function (which returns a pointer), make a deposit using the pointer, and display the account details to confirm the balance was modified.

The following inputs will be provided:

  • Line 1: Owner name
  • Line 2: Account number
  • Line 3: Deposit amount (float)

Output format:

Account: [AccountNumber]
Owner: [Owner]
Balance: [Balance]

For example, given John Smith, ACC-12345, and 500.50, your output should be:

Account: ACC-12345
Owner: John Smith
Balance: 500.50

Remember that your NewAccount function should return *BankAccount using the & operator, and your Deposit function can modify the balance directly through the pointer using Go's automatic dereferencing (e.g., account.Balance instead of (*account).Balance).

Cheat sheet

A pointer to a struct holds the memory address of a struct instance. Create struct pointers using the & operator:

type Person struct {
    Name string
    Age  int
}

p := Person{Name: "Alice", Age: 30}
ptr := &p  // pointer to existing struct

// Or create directly
ptr2 := &Person{Name: "Bob", Age: 25}

Go provides automatic dereferencing when accessing struct fields through a pointer. Instead of (*ptr).Name, you can write ptr.Name:

ptr := &Person{Name: "Alice", Age: 30}

// Both work identically
fmt.Println((*ptr).Name)  // explicit dereference
fmt.Println(ptr.Name)     // automatic dereference

Changes through a pointer affect the original struct:

p := Person{Name: "Alice", Age: 30}
ptr := &p

ptr.Age = 31           // modifies original
fmt.Println(p.Age)     // 31

Struct pointers enable methods to modify receiver state, allow efficient passing of large structs to functions, and form the foundation for linked data structures.

Try it yourself

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)
	
	// Read owner name
	ownerName, _ := reader.ReadString('\n')
	ownerName = strings.TrimSpace(ownerName)
	
	// Read account number
	accountNumber, _ := reader.ReadString('\n')
	accountNumber = strings.TrimSpace(accountNumber)
	
	// Read deposit amount
	amountStr, _ := reader.ReadString('\n')
	amountStr = strings.TrimSpace(amountStr)
	amount, _ := strconv.ParseFloat(amountStr, 64)
	
	// TODO: Create a new account using NewAccount function (returns a pointer)
	
	// TODO: Make a deposit using the Deposit function with the account pointer
	
	// TODO: Print the account details in the required format:
	// Account: [AccountNumber]
	// Owner: [Owner]
	// Balance: [Balance]
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming