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。