【Golang基础】类型和值
文章目录
类型匹配
通过定义类型声明的类型都是不相同的,其他类型可以通过其底层类型是否相同来判断。go 基础类型可以通过以下规则判断是否相同:
- 数组类型:相同的元素类型 & 相同的数组长度
- Slice:相同的元素类型
- Struct:相同的字段顺序 & 对应字段有相同的名称、相同的类型、相同的Tag;不同包的未导出字段肯定是不相同的
- 指针类型:相同的基础类
- 函数类型:相同个数的参数和返回值 & 对应参数和返回值类型相同,有可变参数也要一致,参数和返回值名称不要求一致。
- interface:相同名称和类型的函数的方法集(顺序无关);不同包的未导出方法肯定是不相同的。
- map:两个 map 的 key 和 value 的类型分别相同
- channel:相同的元素类型和数据流向
type (
A0 = []string
A1 = A0
A2 = struct{ a, b int }
A3 = int
A4 = func(A3, float64) *A0
A5 = func(x int, _ float64) *[]string
)
type (
B0 A0
B1 []string
B2 struct{ a, b int }
B3 struct{ a, c int }
B4 func(int, float64) *B0
B5 func(x int, y float64) *A1
)
type C0 = B0
以下类型是相同的:
A0, A1, and []string
A2 and struct{ a, b int }
A3 and int
A4, func(int, float64) *[]string, and A5
B0 and C0
[]int and []int
struct{ a, b *T5 } and struct{ a, b *T5 }
func(x int, y float64) *[]string, func(int, float64) (result *[]string), and A5
B0
和 B1
不相同,是因为其都是定义类型声明的类型。func(int, float64) *B0
和 func(x int, y float64) *[]string
不相同,因为 B0
和 []string
不相同。
可赋值
在满足以下条件时,变量 x
可赋值给类型 T
:
x
的类型与T
相同x
的类型V
与T
有相同的底层类型,并且V
和T
中至少存在一个非定义类型T
是接口类型,并且x
实现了T
x
是双向 channel ,T
是channel 类型,x
的类型V
和T
有相同的元素类型,并且V
和T
中至少存在一个非定义类型x
是预先声明的nil
,并且T
是指针、函数、slice 、map 、channel 或接口类型x
是未类型化的 constant 值,并且其类型为T
比较操作
比较操作比较两个操作数,并且返回一个未类型化的 boolean 值。对于任意的比较操作,第二个操作数类型对第一个操作数来说必须是 可赋值 的,反过来也是一样的。
等值操作 == 和 != 的两个操作数是 可比较 的,比较大小的操作 <
, <=
, >
, 和 >=
的操作数是 可排序 的。
slice | map | function | boolean | integer | 浮点数 | 复数 | 字符串 | 指针类型 | channel | interface | 结构体 | 数组 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
可比较 | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅(动态类型可比较时) | ✅(字段都是可比较的时) | ✅(元素都是可比较的事) |
可排序 | ✅ | ✅ | ✅ |
- 两个复数
u
和v
当real(u) == real(v)
并且imag(u) == imag(v)
时,u
和v
相等 - 两个指针指向同一个变量或均为
nil
时相等;指向不同 ‘zero-size’(空结构体、空数组) 变量的指针,它们可能相等也可能不相等 - 两个 channel 是由相同的
make
调用创建的,或者两个值都为 nil ,它们相等 - 两个 interface 有相同的动态类型和值,或均为 nil ,则它们相同
- 值
x
有非接口类型X
,值t
有接口类型T
,类型T
是可比较的,并且X
实现了T
。当t
的动态类型和X
相同,并且t
的动态值与x
相等时,x
和t
是相等的。 - 两个结构体的对应非空白标志(由
_
标示)相等,则它们相等 - 两个数组中各个对应的元素相等,那么它们相等
slice
、map
和 function
是不可比较的,但都可以与预定义的 nil
进行比较。当两个接口值的动态类型是 不可比较 的,并且在代码中进行了比较时,会导致 panic。这种行为不只是接口值,还包含接口数组或包含接口的结构体。
func main() {
f1 := make([]int, 0)
f2 := make([]int, 0)
var i1 interface{}
var i2 interface{}
i1, i2 = f1, f2
println(i1 == i2) //panic
}