среда, 22 апреля 2020 г.

Преобразования в Golang

Выражение 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, должен быть проверен вручную для безопасности типа и не может быть переносимым.


Читайте также:


Комментариев нет:

Отправить комментарий