A Quiz of Equal Operator in Go
Here is a quiz of ==
(equal operator) in Go, if you pass all of them, you could skip this article. Otherwise, you may want to check the explanation below.
Quiz
Assume the statements of every quiz is inside of a separate function body. For brevity, I will skip the function signature.
// 1
a := []int{1, 2, 3}
b := []int{1, 2, 3}
fmt.Println(a == b)// 2
a := [3]int{1, 2, 3}
b := [3]int{1, 2, 3}
fmt.Println(a == b)// 3
a := [4]int{1, 2, 3}
b := [4]int{1, 2, 3}
fmt.Println(a == b)// 4
a := map[string]bool{"go": true}
b := map[string]bool{"go": true}
fmt.Println(a == b)// 5
a := func(n int) bool { return n%2 == 0 }
b := func(n int) bool { return n%2 == 0 }
fmt.Println(a == b)// 6
a := []int{1, 2, 3}
b := []int{1, 2, 3}
fmt.Println(&a == &b)
Answers
1
Failed to build
invalid operation: a == b (slice can only be compared to nil)2
true3
true4
Failed to build
invalid operation: a == b (map can only be compared to nil)5
Failed to build
invalid operation: a == b (func can only be compared to nil)6
false
Explanation
Slice literal and array literal
In Quiz 1 []int{1, 2, 3}
is a slice literal , whereas in Quiz 2, we have an array literal [3]int{1, 2, 3}
.
Thus, a
and b
in Quiz 1 has type Slice
, while a
and b
in Quiz 2 has type Array
.
If you are not familiar with slice, and wonder how it is related to array, you can check this blog post: https://blog.golang.org/slices.
The length of an array literal is the length specified in the literal type. If fewer elements than the length are provided in the literal, the missing elements are set to the zero value for the array element type.
buffer := [10]string{} // len(buffer) == 10
intSet := [6]int{1, 2, 3, 5} // len(intSet) == 6]
days := [...]string{"Sat", "Sun"} // len(days) == 2
(…)
A slice literal has the form
[]T{x1, x2, … xn}
and is shorthand for a slice operation applied to an array:
tmp := [n]T{x1, x2, … xn}
tmp[0 : n]
Since the missing element in array literal are set to the zero value of the corresponding element type, we know in Quiz 3, [4]int{1, 2, 3}
will yield an array [1, 2, 3, 0]
, since zero value of int
is 0
.
Array values are comparable if values of the array element type are comparable. Two array values are equal if their corresponding elements are equal.
Now we know why Quiz 2 and Quiz 3 both have answer true
, since in those two scenarios, both a
and b
are array of integer and they contains the same elements.
Slice, map and function value can only compare to nil
Slice, map, and function values are not comparable. However, as a special case, a slice, map, or function value may be compared to the predeclared identifier
nil
.
This explains why Quiz 1, 4, 5 is failed to build.
If you want to know more about function value, you could check my previous article: Write a Nested Recursive Function in Go.
By the way, don’t ever try to fool the compiler by converting uncomparable values to interface{}
:
a := []int{1, 2, 3}
b := []int{1, 2, 3}
ai := interface{}(a)
bi := interface{}(b)
fmt.Println(ai == bi)
This will panic in the runtime:
$ go run main.go
panic: runtime error: comparing uncomparable type []int
A comparison of two interface values with identical dynamic types causes a run-time panic if values of that type are not comparable. This behavior applies not only to direct interface value comparisons but also when comparing arrays of interface values or structs with interface-valued fields.
Keep in mind, compiler is your friend not your enemy.
Pointer values are comparable
Pointer values are comparable. Two pointer values are equal if they point to the same variable or if both have value
nil
.
This explains why Quiz 6 is succeeded to build but yield false
.
By the way, comparison of pointers to zero-size variables is not guaranteed to yield true
:
Pointers to distinct zero-size variables may or may not be equal.
— The Go Programming Language Specification
Two distinct zero-size variables may have the same address in memory.
So you should check the underlying variables instead if you think the pointers you compare could point to zero-size variables.
Conclusion
I hope you have learned a little bit more about Go through this quiz.
Who know there are so many stuffs behind, even though this only touch a tip of the equal operator. I plan to write a separate article to investigate the equality for user-defined data structure. Stay tuned.
Thank you for reading and stay safe :)