← Back to articles

Learning Go (10): pointers and nil

Part 10 of my Go fundamentals notes: pointers, initialization, swapping values, and nil.

Pointers

A pointer is a variable whose value is another variable’s memory address.

Pointer size is fixed for a given architecture: 4 bytes on a 32-bit system and 8 bytes on a 64-bit system.

1. Declaring and using pointers

Address operator: &

Pointer type and dereference operator: *

Pass an address and receive it through a pointer.

Declare a pointer:

var a int = 10
var p *int = &a
// 定义了一个指针,p的类型为*int,p指向a的地址

//通过指针修改值
*p = 20
fmt.Println(a) //20

Unlike C/C++, ordinary Go pointers do not support arithmetic for accessing other memory locations.

The unsafe package provides facilities for working with memory addresses, but these operations bypass normal safety guarantees and should not be the default approach.

2. Initializing pointers

An uninitialized pointer has the zero value nil.

Before dereferencing a pointer, make sure it points to a valid value.

Here are alternative initialization forms. Choose the appropriate one; do not paste all of them into the same scope:

var a int = 10

var p *int = &a

var p2 = new(int) //new函数返回一个指针,指向一个新的int类型的值,值为0

// 如果是结构体还能用下面的方式
p := &Person{}

Use & to take an existing variable’s address, new to allocate a zero-valued object, or a form such as &Person{} for a struct.

Use make when initializing maps, slices, and channels.

A pointer must reference a valid object before dereferencing. A nil map can be read, but must be initialized before writing.

3. Swapping values with pointers

func swap(a, b *int) {
	t := *a
	*a = *b
	*b = t
}

func main() {
	var a int = 10
	var b int = 20
	swap(&a, &b)
	fmt.Println(a, b) //20 10
}

4. nil in Go

nil is the zero value available to pointers, slices, maps, channels, functions, and interfaces. It is not a universal zero value: integers use 0, booleans use false, and each struct field has its own zero value.

Two details are easy to misremember: you can append to a nil slice; you can read a nil map, but cannot write to it directly。

package main

import "fmt"

func main() {
	var nums []int
	nums = append(nums, 1)
	fmt.Println(nums) // [1]

	var counts map[string]int
	fmt.Println(counts["go"]) // 0
	// counts["go"] = 1 // nil map 写入会 panic
	counts = make(map[string]int)
	counts["go"] = 1
	fmt.Println(counts["go"]) // 1
}

Both empty and nil slices can have length 0, but the result of slice == nil differs. Two slices also cannot be compared directly with == as two integers can.

An interface containing a typed nil pointer may itself be non-nil. Keep that in mind when returning errors: nil does not simply mean that every kind of value is empty.

See the Go specification for append、index expressions and zero values。

About this article’s date

The date recorded on the old site is retained; writing may have started earlier.

In this series · Go fundamentals

PreviousLearning Go (9): structs and methods ←NextLearning Go (11): interfaces →