Let’s talk about addresses.
Address operators
For an operand
x
of typeT
, the address operation&x
generates a pointer of type*T
tox
. The operand must be addressable, that is, either a variable, pointer indirection, or slice indexing operation; or a field selector of an addressable struct operand; or an array indexing operation of an addressable array.
This leads to one of my great annoyances about the Go language. It annoys me so much, I talked about it in one of my videos. Because a literal or constant is not addressable, it is impossible to do this in Go:
var pointerToInt = &3
This means if you want to instantiate a pointer to a literal value, you have to do something fairly awkward. Here are some options:
var pointerToInt = &[]int{3}[0] // A slice indexing operation is addressable, so this works
var actualInt = 3
var pointerToInt = &actualInt
Now that we have generics in Go, you can also create a general purpose helper function. I usually add it as the only function in a package called ptr
in my project:
package ptr
func To[T any](v T) *T {
return &v
}
then I can do:
var pointerToInt = ptr.To(3)
… As an exception to the addressability requirement,
x
may also be a (possibly parenthesized) composite literal.
In other words, these are possible, even though it shouldn’t be, according to the above rules:
var pointerToSlice = &[]string{"foo", "bar", "baz"}
var pointerToStruct = &struct{
Name string
}{
Name: "Bob",
}
… If the evaluation of
x
would cause a run-time panic, then the evaluation of&x
does too.For an operand
x
of pointer type*T
, the pointer indirection*x
denotes the variable of typeT
pointed to byx
. Ifx
isnil
, an attempt to evaluate*x
will cause a run-time panic.
I’m sure you’ve run into the annoying panic: runtime error: invalid memory address or nil pointer dereference
message more times than you can count.
This is where that comes from.
For examples, the spec gives us some of its own:
&x &a[f(2)] &Point{2, 3} *p *pf(x) var x *int = nil *x // causes a run-time panic &*x // causes a run-time panic
Quotes from The Go Programming Language Specification Language version go1.22 (Feb 6, 2024)