2 gotchas about string, runes and slices

Even after practicing Golang for years, I can be surprised by some elementary features.
Today, I fixed a bug by taking cognizance of two peculiarities of Golang. Let me tell you.

Size of a string

If you don’t work with special characters, that may not interest you.

That first gotcha is very simple.
The builtin “len” applied on a string returns… the number of bytes. And not the number of letters.

func main() {
	a := "aééé"
	b := []rune(a)
	fmt.Println(len(a))
	fmt.Println(len(b))
}

You got…

7
4

https://play.golang.org/p/xs4XC8DkV4

I must confess… that was in the specifications.
https://golang.org/ref/spec#String_types

The kind of detail you can forget easily !

What does it mean for a slice to be nil ?

I took the habit to check the emptiness of a slice by comparing it to nil
It’s a gotcha. Look at this.

func main() {
 
	a := []int{1, 2, 3}
	var b []int
	a = a[:0] // Manual clean
 
	fmt.Println(a)
	fmt.Println(b)
 
	if a == nil {
		fmt.Println("a is nil")
	} else {
		fmt.Println("a is not nil")
	}
	if b == nil {
		fmt.Println("b is nil")
	} else {
		fmt.Println("b is not nil")
	}
}

And you got…

[]
[]
a is not nil
b is nil

https://play.golang.org/p/U7YpfI1mDA

Checking == nil is somewhat easier to write, but also insufficient to test emptiness of the slice.

Was it told in the specifications ?
Somewhat. Not clearly.
https://golang.org/ref/spec#Slice_types

That kind of detail can be a big loss of time.

I hope you may have gained some precious moments of debugging!

Entrepreneur – Cofounder at Golem.ai (Paris, France)

I enjoy sharing Golang interesting patterns, experiments and tips.

Leave a Reply

Your email address will not be published. Required fields are marked *