问题
I've discovered the following peculiarity:
b := "a"[0]
r := 'a'
fmt.Println(b == r) // Does not compile, cannot compare byte and rune
fmt.Println("a"[0] == 'a') // Compiles and prints "true"
How does this work?
回答1:
This is an example of untyped constants. From the docs:
Untyped boolean, numeric, and string constants may be used as operands wherever it is legal to use an operand of boolean, numeric, or string type, respectively. Except for shift operations, if the operands of a binary operation are different kinds of untyped constants, the operation and, for non-boolean operations, the result use the kind that appears later in this list: integer, rune, floating-point, complex.
Since 'a'
is an untyped constant, the compiler will try to convert it to a type comparable with the other operand. In this case, it gets converted to a byte
.
You can see this not working when the rune constant does not fit into a single byte:
package main
import (
"fmt"
)
func main() {
const a = '€'
fmt.Println("a"[0] == a) // constant 8364 overflows byte
}
https://play.golang.org/p/lDN-SERUgN
回答2:
Rune literal 'a' represents a rune constant. Constant may be untyped. In short declaration form r := 'a'
rune constant 'a'
is implicitly converted in its default type which is rune
. But you can explicitly convert it by assigning to typed variable.
var r byte = 'a'
See it works https://play.golang.org/p/lqMq8kQoE-
来源:https://stackoverflow.com/questions/37039678/what-are-gos-rules-for-comparing-bytes-with-runes