2016-01-15 3 views
3

Я только начал идти сегодня, так что это может быть очевидно, но я ничего не мог найти на нем.Как работают функции int-to-string в Go?

Что делает var x uint64 = 0x12345678; y := string(x)y?

Я знаю, что var x uint8 = 65; y := string(x) даст y байт 65, символ A, и здравый смысл подсказывает (поскольку типы больше, чем uint8 разрешено быть отлиты в строки), что они будут просто быть упакованы в родной порядок байтов (т.е. мало endian) и присваивается переменной.

Это, кажется, не быть:

hex.EncodeToString([]byte(y)) ==> "efbfbd" 

Первая мысль говорит, что это адрес с последнего байта остаться от из-за какой-то странной нулевой терминатор штуковина, но если я выделяю два x и y переменные с двумя разными значениями и распечатать их, я получаю тот же результат.

var x, x2 uint64 = 0x10000000, 0x20000000 
y, y2 := string(x), string(x2) 
fmt.Println(hex.EncodeToString([]byte(y))) // "efbfbd" 
fmt.Println(hex.EncodeToString([]byte(y2))) // "efbfbd" 

раздражающе Я не могу найти реализацию для строки типа в любом месте, хотя я, наверное, не выглядел достаточно трудно.

ответ

5

Это описано в Spec: Conversions: Conversions to and from a string type:

Преобразование знаком или без знака целое значение в тип строки дает строку, содержащую представление UTF-8 целого числа. Значения за пределами допустимых кодовых точек Unicode преобразуются в "\uFFFD".

Так эффективен при преобразовании числового значения в string, он может только дает string, имеющий один rune (характер). А так как Go магазинов strings как в UTF-8 закодированных последовательность байт в памяти, то есть то, что вы увидите, если вы преобразовать ваш string в []byte:

Преобразование значения строкового типа ломтика выходов типа байт срез, чьи последующие элементы являются байтами строки.

При попытке CONVER значения по 0x12345678, 0x10000000 и 0x20000000 к string, так как они находятся вне диапазона допустимых кодовых точек Unicode, согласно спецификации, они преобразуются в "\uFFFD", которые в UTF-8 кодирование []byte{239, 191, 189} ; при кодировании в шестнадцатеричную строку:

fmt.Println(hex.EncodeToString([]byte("\uFFFD"))) // Output: efbfbd 

Или просто:

fmt.Printf("%x", "\uFFFD") // Output: efbfbd 

Прочитайте сообщение в блоге Strings, bytes, runes and characters in Go для получения более подробной информации о string внутренностях.

И кстати, так как Go 1.5 исполняющая Go осуществляется (в основном) в Go, так что эти преобразования теперь реализованы в Go и могут быть найдены в runtime упаковке: runtime/string.go, обратите внимание на функцию intstring().

Смежные вопросы