本文将介绍go语言中的各种类型和go类型系统中的各种概念。 不知道这些概念,将很难理解go语言。
概念:基本类型
go语言中的内置类型已经在《内置基本类型和基本值》中介绍过了。为了本文的完整性,在此再次列出内置的基本类型
- 内置字符串类型: string.
- 内置布尔类型: bool.
- 内置数字类型:int,int8,uint8,int16,uint16,int32,uint32,int64,uint64,uint,,uintprt,
float32,float64, complex64,complex128.
除了字符串类型,Go101文章系统将不会解释其他基本类型。
概念: 组合类型
Go 支持下面的组合类型:
- 指针类型
- 结构体类型
- 函数类型
- 容器类型:数组,切片,map
- channel :用来在goroutine之间同步数据
- interface: 在反射和多态中扮演重要角色。
复合类型可以表示为它们各自的类型文字。以下是各种复合类型的一些文字表示示例。
// Assume T is an arbitrary type and Tkey is // a type supporting comparison (== and !=). *T // a pointer type [5]T // an array type []T // a slice type map[Tkey]T // a map type // a struct type struct { name string age int } // a function type func(int) (bool, string) // an interface type interface { Method0(string) int Method1() (int, bool) } // some channel types chan T chan<- T <-chan T
事实:各种类型
上述基本和复合类型中的每一种对应于一种类型。除了这些类型之外,unsafe包中引入的unsafe 指针类型也属于一种类型。
到目前为止(go1.12)go有26种类型。
语法:类型定义
在go语言中,我们可以通过下面的方式定义新的类型。在语法上type
是个关键词。
type NewTypeName SourceType type ( NewTypeName1 SourceType1 NewTypeName2 SourceType2 )
新的类型名字必须是个标识符。
上例中的第二种类型声明包括两种类型规范。如果类型声明包含多个类型规范,则类型规范必须包含在一对()中。
注意:
- 新定义的类型和他对应的原来的类型在类型定义上属于两个完全不同的类型
- 在两个type定义上定义的类型总是不同的类型
- 新定义的类型和源类型将会共用相同的底层类型,他们的值可以相互转换。
- 可以在函数内定义类型
一些类型定义的例子:
// The following new defined and source types are all basic types. type ( MyInt int Age int Text string ) // The following new defined and source types are all composite types. type IntPtr *int type Book struct{author, title string; pages int} type Convert func(in0 int, in1 bool)(out0 int, out1 string) type StringArray [5]string type StringSlice []string func f() { // The names of the three defined types // can be only used within the function. type PersonAge map[string]int type MessageQueue chan string type Reader interface{Read([]byte) int} }
语法:类型别名声明
type ( Name = string Age = int ) type table = map[string]int type Table = map[Name]Age
概念: 定义的类型和非定义的类型
一个定义的类型是一个在类型定义或者类型别名中定义的。
所有的基本类型都是定义的。非定义类型一定是组合类型。
在下面的例子中,别名类型C和类型文字[]string 都是非定义类型,但是类型A和B都是定义类型
type A []string type B = A type C = []string
概念:命名类型和匿名类型
在go语言中:
- 如果一个类型有一个名字,那这个名字一定是标识符,而且不是空标识符。这个类型就被称为命名类型。 所有基本类型都是命名类型,当一个类型声明是标识符非空的话它也是命名类型。
概念: 标的类型
在go语言中,每个类型都有一个标的类型。规则是:
- 对于内置类型,他们的标的类型就是他们自己
- unsafe pointer的标的类型都是
unsafe.Pointer
,这在标准库中定义。 - 一个匿名类型的标的类型 是它自己
- 在类型声明中,新声明的类型和源类型有相同的标的类型
例如:
// The underlying types of the following ones are both int. type ( MyInt int Age MyInt ) // The following new types have different underlying types. type ( IntSlice = []int // underlying type is []int MyIntSlice []MyInt // underlying type is []MyInt AgeSlice []Age // underlying type is []Age ) // The underlying types of Ages and AgeSlice are both []Age. type Ages AgeSlice
给出一个声明的类型,如何追踪它的标的类型呢?规则是,当遇到一个内置基本类型,unsafe.Pointer
或者匿名类型时,和追踪将被终止。以上面的类型声明为例,我们追踪一下他们的标的类型。
MyInt → int Age → MyInt → int IntSlice → []int MyIntSlice → []MyInt → []int AgeSlice → []Age → []MyInt → []int Ages → AgeSlice → []Age → []MyInt → []int
在go语言中:
- 标的类型为bool的类型是布尔类型
- 标的类型为内置的整型的成为整型
- 标的类型为float32,float64的为浮点类型
- 标的类型为complex64,complex128的为复数类型
- 整数,浮点数和复数也被成为数字类型
- 标的类型为string的类型被称为字符串类型
概念: 值
一个类型的实例被成为这种类型的一个值。
每种类型都有一个0值
概念: 值部件
每个值部件占领一段连续的内存,间接标的部件被他的直接部件通过指针引用。
在运行时,很多值都是存在内存中的。在go中,每个这种值都有一个直接的部件。然而有些有一个或者多个间接部件。
原文始发于:Go语言的类型系统概览