Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are Go's rules for comparing bytes with runes?

Tags:

go

byte

rune

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?

like image 840
EMBLEM Avatar asked May 04 '16 23:05

EMBLEM


People also ask

What is the difference between rune and byte?

The byte data type represents ASCII characters while the rune data type represents a more broader set of Unicode characters that are encoded in UTF-8 format.

How many bytes is a Go?

Like byte type, Go has another integer type rune . It is aliases for int32 (4 bytes) data types and is equal to int32 in all ways.

How do I compare byte arrays in Go?

In the Go slice, you are allowed to compare two slices of the byte type with each other using Compare() function. This function returns an integer value which represents that these slices are equal or not and the values are: If the result is 0, then slice_1 == slice_2.

What is a rune Go?

rune in Go is a data type that stores codes that represent Unicode characters. Unicode is actually the collection of all possible characters present in the whole world. In Unicode, each of these characters is assigned a unique number called the Unicode code point. This code point is what we store in a rune data type.


1 Answers

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

like image 115
Tim Cooper Avatar answered Sep 17 '22 20:09

Tim Cooper