Pointers in Go

This blog post was originally a comment on a Google Plus page, but apparently one cannot create a href to a comment so it was suggested I rewrite it as a blog post.

Go pointers, like C pointers, are values that, uh, point to other values. This is a tremendously important concept and shouldn’t be considered dangerous or something to get hung up on.

Here are several ways that Go improves over C pointers, and C++, for that matter.

  1. There is no pointer arithmetic. You cannot write in Go
    var p *int

    That is, you cannot alter the address p points to unless you assign another address to it.

  2. This means there is no pointer/array duality in Go. If you don’t know what I’m talking about, read this book. Even if you have no intention of programming in C or Go, it will enrich your life.
  3. Once a value is assigned to a pointer,¬†with the exception of nil which I’ll cover in the next point, Go guarantees that the thing being pointed to will continue to be valid for the lifetime of the pointer. So
    func f() *int { 
            i := 1
            return &i

    is totally safe to do in Go. The compiler will arrange for the memory location holding the value of i to be valid after f() returns.

  4. Nil pointers. Yes, you can still have nil pointers and panics because of them, however in my experience the general level of hysteria generated by nil pointer errors, and the amount of defensive programming present in other languages like Java is not present in Go.

    I believe this is for two three reasons

    1. multiple return values, nil is not used as a sentinel for something went wrong. Obviously this leaves the question of programmers not checking their errors, but this is simply a matter of education.
    2. Strings are value types, not pointers, which is the, IMO, the number one cause of null pointer exceptions in languages like Java and C++.
      var s string // the zero value of s is "", not nil
    3. In fact, most of the built in data types, maps, slices, channels, and arrays, have a sensible default if they are left uninitialized. Thanks to Dustin Sallings for pointing this out.


  1. The Go wiki states that a slice is “conceptually” a struct with a field which is a pointer to an array. It recommends that functions should accept slices rather than arrays (because Go is pass by value). That makes sense since copying a small struct is more efficient than copying the whole array.

    But I see code like this:

    type Foo *[]Bar // 1
    type Foo []*Bar // 2

    It is code like this which confuses me.
    In #1, you have a type which is a pointer to slices. I don’t see the benefit of this. In #2, I don’t even know what to make of it.
    Basically what is wrong with

    type Foo []Bar

    1. I can’t find that example in my article, or the Go spec, can you tell me where you saw it.

      While unusual the construction *[]Bar, a pointer to slice of Bar values, may be useful if the function needs to alter the callers copy of the slice.

Comments are closed.