Checking that non-pointer struct values are not nil in Golang

This is a quick post of a quirk in Go I only just noticed. The operation described in the title of this article is actually meant to be impossible. If you attempt to compile the following code, the compiler will cry at you.

package main

import (
  "fmt"
)

type MyTestStruct struct {
  AVal int
}

func main() {
  var aStruct MyTestStruct
  aStruct = MyTestStruct{AVal: 15}
 
  if aStruct != nil {
    fmt.Println(aStruct)
  }
}

Will result in this –

tmp/sandbox571559376/main.go:15: cannot convert nil to type MyTestStruct

Program exited.

You can see for yourself here.

The Quirk

If you store the MyTestStruct value into an interface, you can do the test. The code below demonstrates this.

package main

import (
  "fmt"
)

type Incrementable interface {
  Increment() int
}

type MyTestStruct struct {
  AVal int
}

func (s MyTestStruct) Increment() int {
  s.AVal++
  return s.AVal
}

func main() {
  aStruct := MyTestStruct{10}
  var incrementable Incrementable
  incrementable = aStruct
 
  if incrementable != nil {
    fmt.Println(incrementable.Increment())
  }
}

This will give you this output.

11

Program exited.

You can test this yourself here.

This is of course exactly how interfaces are meant to work, but the fact that it does just feels a bit odd. I did further investigation by reflecting the type of both “incrementable” and “aStruct” and they both come back as “MyTestStruct”.

Conclusion

I’ve only just noticed this quirk as assigning a non-pointer type to an interface variable isn’t a common operation for me. As such, I haven’t had enough time to think about or test the implications of this on broader architecture but my “developer spidey-sense” tells me there could be either opportunities or, more likely, potential caveats to this behaviour.

Uncategorized

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s