четверг, 13 июня 2019 г.

Спецификация Go: преобразования

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

Явное преобразование - это выражение в форме T(x), где T - это тип, а x - это выражение, которое можно преобразовать в тип T.

Conversion = Type "(" Expression [ "," ] ")" .

Если тип начинается с оператора * или <-, или если тип начинается с ключевого слова func и не имеет списка результатов, его необходимо заключить в скобки когда необходимо, чтобы избежать двусмысленности:

*Point(p)        // тоже что и *(Point(p))
(*Point)(p)      // p преобразовано в *Point
<-chan int(c)    // тоже что и <-(chan int(c))
(<-chan int)(c)  // c преобразовано в <-chan int
func()(x)        // сигнатура функции func() x
(func())(x)      // x преобразовано в func()
(func() int)(x)  // x преобразовано в func() int
func() int(x)    // x преобразовано в func() int (однозначно)

Постоянное значение x может быть преобразовано в тип T, если x представимо значением T. В особом случае целочисленная константа x может быть явно преобразована в строковый тип, используя то же правило, что и для непостоянной переменной x.

Преобразование константы дает типизированную константу как результат.

uint(iota)               // iota значение типа uint
float32(2.718281828)     // 2.718281828 типа float32
complex128(1)            // 1.0 + 0.0i типа complex128
float32(0.49999999)      // 0.5 типа float32
float64(-1e-1000)        // 0.0 типа float64
string('x')              // "x" типа string
string(0x266c)           // "♬" типа string
MyString("foo" + "bar")  // "foobar" типа MyString
string([]byte{'a'})      // не константа: []byte{'a'} это не константа
(*int)(nil)              // не константа: nil это не константа, *int это не boolean, numeric, или string тип
int(1.2)                 // недопустимо: 1.2 не может быть представлено как int
string(65.0)             // недопустимо: 65.0 iэто не integer константа

Непостоянное (non-constant) значение x может быть преобразовано в тип T в любом из следующих случаев:

  • х присваиваемо (assignable) Т.
  • игнорируя теги struct, тип x и T имеют идентичные базовые типы.
  • игнорируя теги struct, тип x и T являются типами указателей, которые не являются определенными типами, и их базовые типы указателей имеют идентичные базовые типы.
  • Тип x и T оба являются целочисленными или числами с плавающей точкой.
  • Тип x и T оба являются сложными типами.
  • x - целое число или срез байтов или рун, а T - строковый тип.
  • x - это строка, а T - срез байтов или рун.

Структурные теги игнорируются при сравнении структурных типов на идентичность с целью преобразования:

type Person struct {
  Name    string
  Address *struct {
    Street string
    City   string
  }
}

var data *struct {
  Name    string `json:"name"`
  Address *struct {
    Street string `json:"street"`
    City   string `json:"city"`
  } `json:"address"`
}

// игнорируя теги, базовые типы идентичны
var person = (*Person)(data)  

Особые правила применяются к (неконстантным) преобразованиям между числовыми типами или в и из строкового типа. Эти преобразования могут изменить представление x и повлечь за собой затраты времени выполнения. Все остальные преобразования изменяют только тип, но не представление x.

Нет лингвистического механизма для преобразования между указателями и целыми числами. Небезопасный пакет реализует эту функциональность при ограниченных обстоятельствах.


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


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

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