Go Gopher How to Go

Go supports pointers, allowing you to pass references to values and records within your program. Pointers are useful for large structs or when you need to modify a value in a function.

💡 Key Points

  • Pointers store memory addresses of values
  • Use & to get a pointer to a variable
  • Use * to dereference a pointer and access its value
  • Zero value of a pointer is nil
  • Dereferencing a nil pointer causes a runtime panic
  • Go does not support pointer arithmetic (unlike C/C++)
  • Pointers enable functions to modify arguments
  • Use pointers for large structs to avoid copying overhead
  • Methods with pointer receivers can modify the receiver
  • Struct field access through pointers is automatically dereferenced

Basic Pointer Operations

Pointers hold the memory address of a value. Use & to get a pointer and * to dereference:

package main

import "fmt"

func main() {
    i := 42
    
    // Get pointer to i with &
    p := &i
    
    fmt.Println("Value of i:", i)
    fmt.Println("Address of i:", p)
    fmt.Println("Value at pointer:", *p)
    
    // Modify value through pointer
    *p = 21
    fmt.Println("New value of i:", i)
    
    // Zero value of pointer is nil
    var ptr *int
    fmt.Println("Nil pointer:", ptr)
}
Output:
Value of i: 42
Address of i: 0xc000012028
Value at pointer: 42
New value of i: 21
Nil pointer: <nil>

Pointers in Functions

Pass pointers to functions to allow them to modify the original value:

package main

import "fmt"

// Function with value parameter (copy)
func zeroValue(val int) {
    val = 0
}

// Function with pointer parameter (reference)
func zeroPointer(ptr *int) {
    *ptr = 0
}

func main() {
    i := 1
    fmt.Println("Initial:", i)
    
    // Pass by value - doesn't modify original
    zeroValue(i)
    fmt.Println("After zeroValue:", i)
    
    // Pass by reference - modifies original
    zeroPointer(&i)
    fmt.Println("After zeroPointer:", i)
}
Output:
Initial: 1
After zeroValue: 1
After zeroPointer: 0

Pointer Syntax

OperatorSyntaxDescriptionExample
Address-of&Get pointer to a variablep := &x
Dereference*Access value at pointerval := *p
Type Declaration*TDeclare pointer to type Tvar p *int
Nil Checkp == nilCheck if pointer is nilif p != nil { }
New Functionnew(T)Allocate memory, return pointerp := new(int)

Pointer Characteristics

FeatureDescriptionNotes
Zero ValueNil for all pointer typesDereferencing nil causes panic
Memory AddressPointers store memory addressesTypically displayed in hexadecimal
Type SafetyPointers are typed*int different from *string
No ArithmeticGo doesn't support pointer arithmeticUnlike C/C++, can't do ptr++
Automatic DerefStruct field access auto-dereferencesp.field instead of (*p).field
Pass by ValueGo passes everything by valuePointers let you "pass by reference"

Common Pointer Patterns

PatternCodeUse Case
Modify in Functionfunc update(p *int) { *p = 10 }Change original value in function
Struct Pointerfunc (p *Person) SetAge(age int)Method that modifies receiver
Optional Valuevar config *ConfigNil indicates absence of value
Large Structfunc process(data *LargeData)Avoid copying large structures
Linked Structurestype Node struct { Next *Node }Build linked lists, trees, graphs
Factory Functionfunc NewPerson() *PersonReturn pointer to new struct

Pointers vs Values

AspectValuePointer
MemoryCopies entire valueCopies memory address only
ModificationCannot modify originalCan modify original value
Nil CheckNot applicableMust check for nil
PerformanceFast for small typesBetter for large structs
SemanticsCopy/independent valueShared/referenced value
SafetyAlways safe to useRisk of nil pointer panic