Приведение типов
Приведение типов
Я давно размышлял, в каком "книжкином месте" поговорить о приведении типов. Почему бы не здесь? Раз так, приступим. Приведение типов - type conversion - в языке Go момент достаточно простой и в то же время важный. Синтаксически это выглядит так: выражение T(v) приводит значение v к типу T. Коротко и просто.
package main
import (
"fmt"
)
func main() {
//байт (uint8) значение 0x40 (HEX) соответствует символу "@"
var b byte = 0x40
var s string = string(b)
fmt.Println(s)
})
//Результат:
//@
В практике программирования часто значения одного типа присваиваются переменным другого типа. Детали же реализации данного процесса разнятся от языка к к языку. В отличие от языка C (а также многих других языков) в Go нет автоматического (неявного) преобразования или приведения типов. Поэтому присвоение или применение каких-либо операторов между сущностями различных типов всегда требует явного (explicit) приведения типов.
//Преобразованине типов не работает!
var i int = 3.14 //Ошибка: constant 3.14 truncated to integer
package main
import (
"fmt"
)
func main() {
var a int = 10
var b byte = 0x01
//Ошибка: invalid operation: a + b (mismatched types int and byte)
fmt.Println(a + b)
//а так - сработает. Вы ВЫНУЖДЕНЫ сделать явное приведение!
fmt.Println(a + int(b))
}
Как видите, привычку свободно обращаться с данными близких, но не идентичных типов, которую мы наверняка могли завести в процессе работы на некотором другом языке программирования, придётся изживать.
Но так ли всё просто с явным приведением типов? Углубимся в детали. Итак, без каких-либо проблем может быть произведено преобразование типов в том случае, когда эти типы относятся к одной и той же категории типов данных (целочисленные, вещественные) при условии, что вы проследите за отсутствием переполнения преобразуемого типа, либо результата математического выражения, в котором использовалось такое преобразование. Неизбежно забегая вперёд отметим, что вполне взаимопреобразуемы будут строки и срезы байтов и рун ([]byte, []rune). Успешным будет и приведение структур, совпадающих сигнатурно. Приведение вещественного типа к целочисленному приведёт к потере (не округлению!) дробной части. Небрежность в соблюдении размерности типов - к переполнению.
package main
import (
"fmt"
)
func main() {
f := 3.14
fmt.Println(int(f))//потеряли дробную часть
i := 256
fmt.Println(byte(i))//переполнение типа
}
//Результат:
//3
//0
Наконец, ожидаемо существуют преобразования, которые не могут быть совершены.
package main
import (
"fmt"
)
func main() {
fmt.Println(bool(0)) // 0 не означает false!
fmt.Println((*int)(0))
}
//Результат:
//cannot convert 0 (type untyped int) to type bool
//cannot convert 0 (type int) to type *int
Last updated
Was this helpful?