一、map类型的key和value可以是啥类型
- key 可以是什么类型
golang 中的 map,的 key 可以是很多种类型,比如 bool, 数字,string, 指针, channel , 还可以是只包含前面几个类型的 接口, 结构体, 数组
通常key为int string
注意: slice, map 还有 function 不可以,因为这几个没法用 == 来判断
- valuetype 可以是什么类型
valuetype 的类型和 key 基本一样,这里我就不再赘述了通常为: 数字(整数,浮点数),string,map,struct
2、值类型(值传递)、引用类型(引用传递)有哪些
其实,不管是值传递还是引用传递,传递给函数的都是变量的副本,不同的是,值传递的是值的拷贝,引用传递的是地址的拷贝,一般来说,地址拷贝效率高,因为数据量小,而值拷贝决定拷贝的数据大小,数据越大,效率越低。
- 值类型 : 基本数据类型 int 系列, float 系列, bool, string 、数组和结构体 struct
- 引用类型:指针、slice 切片、map、管道 chan、interface 等都是引用类型
二、golang中,哪些数据类型是可比较的,哪些是不可比较的:
- 可比较:Integer,Floating-point,String,Boolean,Complex(复数型),Pointer,Channel,Interface,Array
- 不可比较:Slice,Map,Function
struct能不能比较? 很显然这句话包含了两种情况:
- 同一个struct的两个实例能不能比较?
- 两个不同的struct的实例能不能比较?
两个相同的struct的实例能不能比较
package main
import "fmt"
type Stu struct {
Name string
Age int
Address *int
}
func main() {
i := 10
a := Stu{
Name: "aa",
Age: 1,
Address: &i,
}
b := Stu{
Name: "aa",
Age: 1,
Address: &i,
}
fmt.Println(a == b)
}
输出结果:(可比较)
在结构体中加上不可比较类型
直接报错
「总结」
同一个struct的两个实例可比较也不可比较,当结构不包含不可直接比较成员变量时可直接比较,否则不可直接比较
两个不同的struct的实例能不能比较
如果成员变量中含有不可比较成员变量,即使可以强制转换,也不可以比较
三、如果包含不可比较成员变量时,可以使用reflect.DeepEqual 函数来进行比较
Go 语言中提供了一个函数可以完成此项功能:
func DeepEqual(x, y interface{}) bool
DeepEqual
函数的参数是两个 interface
,实际上也就是可以输入任意类型,输出 true 或者 flase 表示输入的两个变量是否是“深度”相等。
先明白一点,如果是不同的类型,即使是底层类型相同,相应的值也相同,那么两者也不是“深度”相等。
type MyInt int type YourInt int func main() { m := MyInt(1) y := YourInt(1) fmt.Println(reflect.DeepEqual(m, y)) // false }
上面的代码中,m, y 底层都是 int,而且值都是 1,但是两者静态类型不同,前者是 MyInt
,后者是 YourInt
,因此两者不是“深度”相等。
在源码里,有对 DeepEqual 函数的非常清楚地注释,列举了不同类型,DeepEqual 的比较情形,这里做一个总结:
类型 | 深度相等情形 |
---|---|
Array | 相同索引处的元素“深度”相等 |
Struct | 相应字段,包含导出和不导出,“深度”相等 |
Func | 只有两者都是 nil 时 |
Interface | 两者存储的具体值“深度”相等 |
Map | 1、都为 nil;2、非空、长度相等,指向同一个 map 实体对象,或者相应的 key 指向的 value “深度”相等 |
Pointer | 1、使用 == 比较的结果相等;2、指向的实体“深度”相等 |
Slice | 1、都为 nil;2、非空、长度相等,首元素指向同一个底层数组的相同元素,即 &x[0] == &y[0] 或者 相同索引处的元素“深度”相等 |
numbers, bools, strings, and channels | 使用 == 比较的结果为真 |
一般情况下,DeepEqual 的实现只需要递归地调用 == 就可以比较两个变量是否是真的“深度”相等。
但是,有一些异常情况:比如 func 类型是不可比较的类型,只有在两个 func 类型都是 nil 的情况下,才是“深度”相等;float 类型,由于精度的原因,也是不能使用 == 比较的;包含 func 类型或者 float 类型的 struct, interface, array 等。
对于指针而言,当两个值相等的指针就是“深度”相等,因为两者指向的内容是相等的,即使两者指向的是 func 类型或者 float 类型,这种情况下不关心指针所指向的内容。
同样,对于指向相同 slice, map 的两个变量也是“深度”相等的,不关心 slice, map 具体的内容。