深入理解golang类型系统
正文开始之前,想抛出一些小问题,读者可以看下,且带着小问题继续往下看
|
|
can it be compiled? that’s question ==1==
can it be compiled? that’s question ==2==
can it be compiled? that’s question ==3==
|
|
can it be compiled? that’s question ==4==
can it be compiled? that’s question ==5==
可能问题有点多,希望读者不要失去耐心~
命名类型(named (defined) type)
具有名称的类型:例如:
等。这些已经是 GO 中预先声明好的类型,
我们通过类型声明(type declaration)创建的所有类型都是命名类型。
一个命名类型一定和其它类型不同!
可以理解成:命名类型是能够直切确定 这个变量是什么数据类型的
未命名类型(unnamed type)
组合类型:
虽然他们没有名字,但却有一个类型字面量(type literal)来描述他们由什么构成。
可以理解成:未命名类型是不能直接确定这个变量是什么类型的,例如:channel 需要知道 是channel int 还是 channel string
基础类型(underlying type)
任何类型 T 都有基本类型
如果 T 是预先声明类型:
否则,T 的基础类型就是 T 所引用的那个类型的类型声明(type declaration)。
解释:
- 第 3,8 行:他们的类型声明为 string的预先声明的类型,所以他们的基础类型就是T它自身: string
- 第 5,7 行:他们有类型字面量,所以他们的基础类型也是T它自身:map[string]int和 *N 指针。注意:这些类型字面量还是 未命名类型(unnamed type)
- 第 4,6,10 行:T的基本类型是T所引用的那个类型的类型声明(type declaration)。
- 4 行:B引用了A,因此B的基础类型是A的类型声明:string,
- 6 行:N引用了M, 因此N的基础类型是M的类型声明:map[string]int
- 需要注意的是第 9 行:type T map[S]int. 由于s的基础类型是string,那么是否type T map[S]int的基础类型应该是 map[string]int 而并非map[S]int呢?确定吗? 在此,我们讨论的是基础未命名类型map[S]int,因为基础类型只追溯到它的未命名类型的最外层(或者就像说明上说的:如果T是一个类型字面量,它的基础类型就是T自身),所以U的基础类型是map[S]int。
你可能在想我为什么如此强调unnamed type, named (defined) type , underlying type 这几个概念,因为它们在 go 语言规范中扮演着重要的角色,他们能帮助我们更好的理解上面的那些代码片段为何有些可以编译通过,有些却不通过。
可赋值性
|
|
这是golang编译规范中的一条
对于question 4:
显然不能编译通过 双方的基础类型不同
类型一致性
两种类型要么相同,要么不相同。
一个命名类型一定和其它类型都不同。
如果他们基础类型的字面量在结构上是等价的,他们就是相同的类型。
因此,预先声明的命名类型 int, int64, 等都是不一致的。
结构体转换规则:
|
|
所以question1可以编译通过,question2不能编译通过
溜了~