Wednesday, September 12, 2012

An intuition/reality clash in Go

The following Go code doesn't compile:
package main

import "log/syslog"

type MyThing struct {
 writer *syslog.Writer
}

func NewMyThing() (thing *MyThing) {
 thing = new(MyThing)
 thing.writer, err := syslog.Dial("", "", syslog.LOG_ERR, "")
 return
}

func main() {
}

It fails with the error prog.go:11: non-name thing.writer on left side of :=.  You can try it yourself here. (Ignore the fact that if it did compile there would be a different error because err is not used; the goal here is a small example).

The reason this fails is that := must be thought of as a declaration and not as an assignment. In fact, := is a declaration with the special exception that if one of the variables on the LHS is already declared in the same block then it is not redeclared it is assigned.

If you think of := as an assignment that sometimes declares you run into trouble because thing.writer can never be declared there (it's already declared in the struct). Just remember that := is a declaration that can assign.

No comments: