原创 lightcity 光城 2020-05-29
Go语言不可比较类型与Map问题
1. 昨日题目的解答
题目1:slice输出结果分析?
s1_ : [2 3 4 5] 4 7
s2_ : [5 6] 2 4
s3_ : [] 0 2
s4_ : [7] 1 2
输出这个结果问题是因为:
先看s1,这个答案比较简答是2 3 4 5,此时切片s1_
是arr的一个view,s1_
有len与cap,此时len=4,cap=7。
s2_
是从s1_
的index=3取,对应数字5,此时还可以向后扩展,超过了len,但没超过cap,此时结果就是5 6,len=2,cap=4。假设这里还有个例子,取出s1_[4]
,由于此时index>=4,不能取出~
s3_
是从s2_
的index=2开始,index=2,s2_
的len=2,此时index=len,由于:
前后只要有省略,取出的元素就是s2_
中的,所以此时是空,len=0,cap=2。
s4_
是从s2_
的index=2开始,index=2,等于len,但是未超越cap,可以向后扩展,拿到元素7。
题目2:验证方法是传递函数即可,例如:
func updateSlice(s []int) {}
值传递slice,可以更改数据,证明slice本身是引用类型。
func print(arr [5]int) {}
func ref_print(arr *[5]int) {}
值传递修改无效,引用传递才会修改,证明array是引用类型。
2.map问题
昨天在做实验,想往map里面插入一个key为map的map,结果发现key不能是map,因为map不可比较,也就是不支持==。而cpp是可以的,cpp支持操作符重载,并且map在cpp中是值类型,而go中是引用类型,那么现在问题来了,为啥map不支持呢?
原因是由于切片,因为切片是引用类型,并且不可比较,为啥不可比较,有两个原因:
- 引用类型,比较地址没有意义。
- 切片有len,cap,比较的维度不好衡量,因此go设计的时候就不允许切片可比较。
由于map中的key可以是slice,这就使得包含slice的结构包括函数,结构体等,也是不可比较的。注意:这里的结构体不可比较指的是包含slice的结构体!
因此map是不可比较的,自然不能作为map的key,而value是任意类型。
一些实践例子:
切片比较:
var a []int
var b []int
fmt.Println(a == b)
报错:invalid operation: a == b (slice can only be compared to nil)。
map比较:
m_1 := map[int]int{}
m_2 := map[int]int{}
if m_1 == m_2 {
fmt.Println("equal")
}
报错:m_1 == m_2 (map can only be compared to nil)
有疑问加站长微信联系(非本文作者)