Go in a nutshell
  • Go in a nutshell
  • Введение
  • Родословная или Should I Go?
  • Hello, world!
  • Базовые типы данных
  • Go - установка, сборка
  • Алфавит и пакеты
  • Синтаксис
  • Приведение типов
  • Операторы
  • Константы
  • Управление потоком
  • Массивы, срезы, отображения
  • Именованные типы и структуры
  • Указатели и оператор new
  • Функции
  • Работа с параметрами командной строки
  • Завершение работы программы
  • Методы
Powered by GitBook
On this page

Was this helpful?

Приведение типов

Приведение типов

Я давно размышлял, в каком "книжкином месте" поговорить о приведении типов. Почему бы не здесь? Раз так, приступим. Приведение типов - 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
PreviousСинтаксисNextОператоры

Last updated 4 years ago

Was this helpful?