Это 18-я статья из серии "Изучаем язык Go".
что такое тип
Концепция типов различается в разных языках программирования и может быть выражена по-разному, но в целом имеет некоторые общие черты.
- Тип — это набор значений;
- Какие операции можно выполнять между значениями одного типа, например: типы int могут выполнять такие операции, как + и -, а для символьных типов могут выполняться такие операции, как конкатенация и проверка на null;
Таким образом, система языковых типов указывает, какие операторы допустимы для каких типов.
Система типов языка Go
boolean, numeric и string — основные типы данных Go, также известные какПредварительно объявленный тип(предварительно объявленный тип), который можно использовать для создания других типов, таких как литеральные типы.
литеральный тип(литерал типа): он состоит из предварительно объявленных типов (не определенных ключевым словом type), например: [3]int, chan int, map[string] string, *int и т. д.
Создается из литеральных типовсоставной тип, такие как: массив, структура, карта, срез, канал, функция, интерфейс и т. д.
Именованные и безымянные типы
Типы с именами: предварительно объявленные типы, такие как int, int64, float32, string, bool и т. д. Кроме того, любой тип, объявленный с помощью ключевого слова type, также называется именованным типом.
var i int // named type
type myInt int // named type
var b bool // named type
Безымянные типы. Упомянутые выше составные типы, включая массив, структуру, указатель, функцию, интерфейс, срез, карту и канал, являются безымянными типами. У них нет имен, но есть буквальные описания того, как они составлены.
[]string // unnamed type
map[string]string // unnamed type
[10]int // unnamed type
базовый тип
У каждого типа есть базовый тип, и если T является предварительно объявленным типом или литеральным типом, базовым типом является сам T; в противном случае базовым типом T является базовый тип типа, на который T ссылается во время определения.
type A string // string
type B A // string
type M map[string]int // map[string]int
type N M // map[string]int
type P *N // *N
type S string // string
type T map[S]int // map[S]int
type U T // map[S]int
Строки 1 и 6, предварительно объявленный строковый тип, поэтому базовым типом является сам T, который является строкой;
Строки 3 и 5 являются литеральными типами, поэтому базовым типом является сам T, а именно map[string]int и указатель *N. Примечание: литеральные типы также являются безымянными типами;
В строках 2, 4 и 8 базовый тип T является базовым типом типа, на который ссылается T, когда он определен, например: B ссылается на A, поэтому базовый тип B является строковым типом, и то же верно и для других случаев;
Давайте еще раз посмотрим на пример в строке 7: type T map[S]int , так как базовым типом S является строка, не должен ли базовый тип T быть map[string]int вместо map[S]int на данном этапе. время? Поскольку мы говорим о базовом безымянном типе map[S]int , мы переходим к безымянному типу, как сказано в спецификации языка Go: если T является буквальным типом, соответствующий базовый тип — это сам T.
уступчивость
Присваиваемость переменных была четко указана в документации языка Go.Давайте рассмотрим одну из наиболее важных: когда переменная a может быть присвоена переменной типа T,Оба должны иметь один и тот же базовый тип, и по крайней мере один из них не является именованным типом..
посмотри на код
package main
type aInt int
func main() {
var i int = 10
var ai aInt = 100
i = ai
printAiType(i)
}
func printAiType(ai aInt) {
print(ai)
}
Приведенный выше код не компилируется, и при компиляции сообщается об ошибке:
8:4: cannot use ai (type aInt) as type int in assignment
9:13: cannot use i (type int) as type aInt in argument to printAiType
Поскольку i — это именованный тип int, а ai — именованный тип aInt, хотя их базовые типы одинаковы, оба они являются int.
package main
type MyMap map[int]int
func main() {
m := make(map[int]int)
var mMap MyMap
mMap = m
printMyMapType(mMap)
print(m)
}
func printMyMapType(mMap MyMap) {
print(mMap)
}
Приведенный выше код компилируется, потому что m — безымянный тип, а базовый тип m и mMap — один и тот же.
преобразование типов
Посмотрите на спецификацию преобразования типов
package main
type Meter int64
type Centimeter int32
func main() {
var cm Centimeter = 1000
var m Meter
m = Meter(cm)
print(m)
cm = Centimeter(m)
print(cm)
}
Приведенный выше код компилируется нормально, потому чтоMeterа такжеCentimeterОба являются целыми числами, и их базовые типы могут быть преобразованы друг в друга.
согласованность типов
Эти два типа либо одинаковые, либо разные.
Определенный тип всегда отличается от любого другого типа. Так что даже заранее объявленные именованные типы int, int64 и т. д. не совпадают.
Давайте посмотрим на правило преобразования для структур:
Когда x присваивается T, независимо от метки структуры, x и T должны иметь один и тот же базовый тип.
package main
type Meter struct {
value int64
}
type Centimeter struct {
value int32
}
func main() {
cm := Centimeter{
value: 1000,
}
var m Meter
m = Meter(cm)
print(m.value)
cm = Centimeter(m)
print(cm.value)
}
Помните это:тот же базовый тип. Поскольку базовым типом члена Meter.value является int64, а базовым типом члена Centimeter.value является int32, они не совпадают, посколькуОпределенный тип всегда отличается от любого другого типа. Таким образом, приведенный выше фрагмент кода компилируется с ошибкой.
package main
type Meter struct {
value int64
}
type Centimeter struct {
value int64
}
func main() {
cm := Centimeter{
value: 1000,
}
var m Meter
m = Meter(cm)
print(m.value)
cm = Centimeter(m)
print(cm.value)
}
Базовые типы членов Meter.value и Centimeter.value оба являются int64, поэтому они одинаковы, и компиляция может пройти.
ps: первая статья, которую я перевел в GCTT (группа китайских переводчиков Go), была о системе типов языка Go. Сегодня я организую ее для всеобщего обозрения. Надеюсь, эта статья поможет вам понять систему типов Go!
(Конец полного текста)
Оригинал статьи, если нужно перепечатать, указывайте источник!
Добро пожаловать, чтобы отсканировать код и подписаться на официальный аккаунт »Голанг здесь” или двигатьсяseekload.net, см. больше замечательных статей.
Публичная учетная запись «Голанг идет» подготовила для вас подарочный пакет для изучения тайны, и ответьте на [электронную книгу] в фоновом режиме, чтобы получить его!