Выражение T(x) преобразует значение x в тип T.
x := 5.1
n := int(x) // преобразует float в int
Правила преобразования обширны, но предсказуемы:
- все преобразования между типизированными выражениями должны быть явно указаны,
- незаконные преобразования обнаруживаются компилятором.
Преобразование в и из чисел и строк может изменить представление и иметь стоимость во время выполнения. Все остальные преобразования изменяют только тип, но не представление x.
Интерфейсы
Чтобы "преобразовать" интерфейс в строку, структуру или карту (map), вы должны использовать утверждение типа или переключатель типа. Утверждение типа в действительности не преобразует интерфейс в другой тип данных, но обеспечивает доступ к конкретному значению интерфейса, которое обычно является тем, что вам нужно.
Целые числа
- При преобразовании в более короткий целочисленный тип значение усекается, чтобы соответствовать размеру типа результата.
- При преобразовании в более длинный целочисленный тип,
- если значение является целым числом со знаком, оно расширяется знаком;
- в противном случае оно расширяется нулями.
a := uint16(0x10fe) // 0001 0000 1111 1110
b := int8(a) // 1111 1110 (усечено к -2)
c := uint16(b) // 1111 1111 1111 1110 (расширено знаком к 0xfffe)
Числа с плавающей запятой
- При преобразовании числа с плавающей запятой в целое число дробь отбрасывается (усечение до нуля).
- При преобразовании целого числа или числа с плавающей запятой в тип с плавающей запятой результирующее значение округляется до точности, указанной типом назначения.
var x float64 = 1.9
n := int64(x) // 1
n = int64(-x) // -1
n = 1234567890
y := float32(n) // 1.234568e+09
Предупреждение. Во всех неконстантных преобразованиях, включающих значения с плавающей запятой или комплексные значения, если тип результата не может представлять значение, преобразование завершается успешно, но значение результата зависит от реализации.
Целое число в строку
- При преобразовании целого числа в строку значение интерпретируется как кодовая точка Unicode, и результирующая строка будет содержать символ, представленный этой кодовой точкой, закодированный в UTF-8.
- Если значение не представляет допустимую кодовую точку (например, если оно отрицательное), результатом будет "\ufffd", символ замены Unicode �.
string(97) // "a"
string(-1) // "\ufffd" == "\xef\xbf\xbd"
Используйте strconv.Itoa, чтобы получить десятичное строковое представление целого числа.
strconv.Itoa(97) // "97"
Строки и срезы байтов
- Преобразование среза байтов в строковый тип дает строку, последовательные байты которой являются элементами среза.
- Преобразование значения типа строки в тип среза байтов дает срез, последовательными элементами которого являются байты строки.
string([]byte{97, 230, 151, 165}) // "a日"
[]byte("a日") // []byte{97, 230, 151, 165}
Строки и срезы рун
- Преобразование среза рун в строковый тип дает строку, которая является объединением отдельных значений рун, преобразованных в строки.
- Преобразование значения типа строки в тип среза рун дает срез, содержащий отдельные кодовые точки Unicode строки.
string([]rune{97, 26085}) // "a日"
[]rune("a日") // []rune{97, 26085}
Подлежащий тип
Неконстантное значение может быть преобразовано в тип T, если оно имеет тот же подлежащий тип, что и T.
В этом примере базовый тип int64, T1 и T2 - int64.
type (
T1 int64
T2 T1
)
В Go идиоматично преобразовывать тип выражения для доступа к определенному методу.
var n int64 = 12345
fmt.Println(n) // 12345
fmt.Println(time.Duration(n)) // 12.345µs
Подлежащий тип time.Duration - int64, а тип time.Duration имеет метод String, который возвращает продолжительность (duration), отформатированную как время.
Неявные преобразования
Единственное неявное преобразование в Go - это когда нетипизированная константа используется в ситуации, когда требуется тип.
В этом примере нетипизированные литералы 1 и 2 неявно преобразуются.
var x float64
x = 1 // То же, что и x = float64(1)
t := 2 * time.Second
// То же, что и t := time.Duration(2) * time.Second
Неявные преобразования необходимы, поскольку в Go нет смешивания числовых типов. Вы можете умножить time.Duration только на другое time.Duration.
Когда тип не может быть выведен из контекста, нетипизированная константа преобразуется в bool, int, float64, complex128, string или rune в зависимости от синтаксического формата константы.
n := 1 // То же, что и n := int(1)
x := 1.0 // То же, что и x := float64(1.0)
s := "A" // То же, что и s := string("A")
c := 'A' // То же, что и c := rune('A')
Незаконные неявные преобразования перехватываются компилятором.
var b byte = 256 // То же, что и var b byte = byte(256)
../main.go:2:6: constant 256 overflows byte
Указатели
Компилятор Go не допускает преобразования между указателями и целыми числами. Пакет unsafe реализует эту функцию в ограниченных условиях.
Предупреждение: встроенный unsafe пакет, известный компилятору, предоставляет средства для низкоуровневого программирования, включая операции, которые нарушают систему типов. Пакет, использующий unsafe, должен быть проверен вручную для безопасности типа и не может быть переносимым.
Читайте также:
- Спецификация Go: преобразования
- Спецификация Go: утверждения типа (type assertions)
- Эффективный Go: интерфейсы, преобразования
- Эффективный Go: преобразования интерфейсов и утверждения типа
Комментариев нет:
Отправить комментарий