Go Pattern: Is Zero Value a Change ?

As we know in Go, variables declared without an explicit initial value are assigned their zero value.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
package main

import "fmt"

type data struct {
	a string
}

func main() {
	var d data
	fmt.Printf("%+v",d)
}
// go run main.go
// output: {a:}

Here a is an empty string. This is ok. Sane defaults.

The problem arises when we want to check if a field’s value has changed to it’s zero value. The solution to this problem is pretty simple.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
package main

import "fmt"

type data struct {
	a *string
}

func main() {
	var d data
	fmt.Printf("%+v",d)
}
// go run main.go
// output: {a:<nil>}

Making the field a pointer to string helps. To keep a field unchanged we simply don’t assign to it. As in the above example, it will be set to zero value of pointer which is nil.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
package main

import "fmt"

type data struct {
	a *string
}

func main() {
	var val string
	d := data{a: &val}
	if d.a == nil {
		// nothing changed
		return
	}

	if *d.a == "" {
		fmt.Println("a's value has changed to an empty string")
	}

}

This is trivial but comes up quite often.