两个类型要么相同要么不一样.
新定义的一个类型,和其他类型都是不一样的.
要判断两个类型是否一致,需要判断底层类型的结构是否一致.
其实很简单:底层类型的结构体字面量是否一致,每个字段的对应的类型是否一致.
如何识别两个类型是一样的:
- 两数组类型相同:表示元素类型和长度都一样
- 两切片类型相同:表示元素类型一样
- 两结构体类型相同:表示字段顺序相同,字段的名字/类型/tag都相同
- 如果是不导出的字段,类型是不同的包,那也是不一样的
- 两指针类型相同:表示基础类型相同
- 两函数类型相同:表示参数/返回值的顺序/类型一致(名字没要求),可变参情况一致
- 两接口类型相同:表示方法集相同(包括里面的函数名和函数类型相同),顺序无所谓
- 同样的,不导出的方法名来之不同的包,那也是不一样的
- 两map类型相同:表示key和value的类型相同
- 两信道类型相同:表示元素类型和方向相同
type a = b 和 type a b 是完全不一样的, 前者是一个别名,a和b本质上是一样的, 后者是新定义一个类型, 我们新定义一个结构体时,是不会用到等号的,因为本意是定义一个新类型, 所以要注意上面特别标明的部分,定义的新类型和所有其他类型都是不同的.
有个变量b的类型是T,如果要将a赋值给b,要满足以下条件之一即可:
- a的类型是T
- a的类型是V,当V和T的底层类型一致,且V和T中至少有一个不是定义类型
- 在我的测试中,发现VT如果有一个是定义类型,赋值会出错
- 定义类型的对象作为右值时,会出错,需要显示转换才行
- 这点估计是spec和实现有差别的地方
- T是接口,a的类型实现了T
- a是双向信道,T是信道类型,a的类型是V,VT她们的元素类型相同,且VT至少有一个不是定义类型
- a是nil,T是指针/函数/slice/map/channel/interface类型
- b是无类型的常量,值可以转换成类型T
我们说某个常量可以表示为某个类型的值,那么这个常量要满足以下条件之一即可:
- 类型T决定了一系列值的集合,b在这个集合中即可。eg:var i int = 0
- T是浮点类型,只要b可以转换之后没有溢出即可
- T是复数类型,b正好可以将实数和虚数转换成T指定的类型(float32/float64)