Преобразование между руной и байтом (срез) - PullRequest
0 голосов
/ 01 августа 2020

Go позволяет преобразовать rune в byte. Но базовый тип для rune - int32 (потому что Go использует UTF-8), а для byte - uint8, поэтому преобразование приводит к потере информации. Однако невозможно преобразовать руну в []byte.

var b byte = '©'
bs := []byte(string('©'))
fmt.Println(b)
fmt.Println(bs)

// Output
169
[194 169]

Рабочий пример

Почему Go допускает преобразование из rune в byte вместо rune на []byte?

Ответы [ 3 ]

5 голосов
/ 01 августа 2020

Go поддерживает преобразование из rune в byte, как и для всех пар типов numeri c. Было бы удивительно особенным случаем, если бы преобразование int32 в byte было бы запрещено.

Но базовым типом для rune является int32 (потому что Go использует UTF-8 )

Здесь упускается важная деталь: rune - это псевдоним для int32. Они одного типа.

Верно, что базовый тип rune равен int32, но это потому, что rune и int32 являются одним и тем же типом, а базовый тип встроенного типа - сам тип.

Представление кодовых точек Unicode как int32 значений не связано с кодировкой UTF-8.

преобразование, следовательно, приводит к потере информации

Да, преобразование между типами numeri c может привести к потере информации. Это одна из причин, почему преобразования в Go должны быть явными.

Обратите внимание, что оператор var b byte = '©' не выполняет никаких преобразований. Выражение '@' - это нетипизированная константа.

Компилятор сообщает об ошибке, если присвоение нетипизированной константы приводит к потере информации. Например, оператор var b byte = '世' вызывает ошибку компиляции.

Все функции кодирования UTF-8 в языке относятся к типу string. Все преобразования, поддерживающие UTF-8, относятся к типу string или наоборот. Преобразование []byte(numericType) может поддерживаться, но это приведет к выходу кодировки UTF-8 за пределы типа string.

Авторы Go сожалеют о включении преобразования string(numericType), потому что это не очень полезно на практике и конверсия - это не то, чего некоторые ожидают. Библиотечная функция - лучшее место для функциональности.

0 голосов
/ 02 августа 2020

Да, можно преобразовать из руны в байт [] (например, через байт) и обратно.

package main

import "fmt"

func main() {
    var b byte = '©'
    bs := []byte{b}
    fmt.Printf("%T %v\n", b, b)   // uint8 169
    fmt.Printf("%T %v\n", bs, bs) // []uint8 [169]

    s := string(bs[0]) // s := string(b) works too.
    r2 := rune(s[0]) // r2 := rune(b) works too.
    fmt.Printf("%T %v\n", s, s) // string ©
    fmt.Printf("%T %v\n", r2, r2) // int32 169
}
0 голосов
/ 01 августа 2020

Причиной такого поведения является та же причина, по которой это разрешено. объем памяти.

Кроме того, для кодирования rune вы можете использовать EncodeRune , который действительно использует []byte.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...