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!