Каковы правила Go для сравнения байтов с рунами?
Я обнаружил следующую особенность:
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"
Как это работает?
2 ответа
Это пример нетипизированных констант. Из документов:
Нетипизированные логические, числовые и строковые константы могут использоваться в качестве операндов везде, где допустимо использовать операнд логического, числового или строкового типа соответственно. За исключением операций сдвига, если операндами бинарной операции являются разные типы нетипизированных констант, операция и, для не булевых операций, результат используют вид, который появляется позже в этом списке: целое число, руна, число с плавающей точкой, сложное,
поскольку 'a'
является нетипизированной константой, компилятор попытается преобразовать ее в тип, сопоставимый с другим операндом. В этом случае он преобразуется в byte
,
Вы можете видеть, что это не работает, когда константа руны не помещается в один байт:
package main
import (
"fmt"
)
func main() {
const a = '€'
fmt.Println("a"[0] == a) // constant 8364 overflows byte
}
Рунический литерал "а" представляет собой константу руны. Константа может быть нетипизирована. В краткой декларации r := 'a'
постоянная руны 'a'
неявно преобразуется в тип по умолчанию, который rune
, Но вы можете явно преобразовать его, присвоив типизированной переменной.
var r byte = 'a'
Смотрите, это работает https://play.golang.org/p/lqMq8kQoE-