请教一个 Golang 中进行比较的问题。
在 Golang 中 slice、map、channel 都是引用类型,因为是引用类型,所以 slice 和 map 不能使用 == 进行比较这里还能理解,可是为什么 channel 可以用 == 进行比较呢??
如下代码
package main
import "fmt"
import _ "reflect"
func main() {
ch1 := make(chan int)
ch2 := make(chan int)
fmt.Println(ch1 == ch2)
s1 := []int{1,2}
s2 := []int{2,1}
fmt.Println(s1 == s2)
m1 := make(map[int]int)
m2 := make(map[int]int)
fmt.Println(m1 == m2)
}
输出结果为
# command-line-arguments
./gotest.go:13:20: invalid operation: s1 == s2 (slice can only be compared to nil)
./gotest.go:17:20: invalid operation: m1 == m2 (map can only be compared to nil)
代码中,slice 和 map 使用 == 进行比较都报错了,为什么 channel 没有呢???
1
LANB0 2019-04-25 20:37:22 +08:00
C++的思维看,大概是 channel 实现了对==的重载,而 slice 和 map 没实现
|
2
reus 2019-04-25 21:13:06 +08:00
go 的 = 操作,就是简单的内存比较
slice 的内存不连续,slice header 和 data 分开放的,所以不能比较 map 的内存不连续,bucket 是分开放的,所以不能比较 chan 的内存是连续的,就一个对象,所以可以比较 |
3
liulaomo 2019-04-26 10:23:05 +08:00 3
在 Go 中,slice/map/function 值不能比较的原因是程序员这些值的比较规则有着不同的看法,所以干脆禁止这些值的比较,以防止引起困惑。
比如,对于 map,有些人认为两个引用着同一个底层哈希表的 maps 相等,有的人则认为这样两者中存储的键值对完全一致,则两者相同。对于这第二种理解,很难处理含有 NaN 键值的 maps。 对于 slice,有些人认为两者的长度和底层元素指针相同则相等,有些人认为两者的长度 /容量和底层元素指针必须都相等,有些人认为底层元素指针不必相等,只要它们对应的元素一一相等即可。 因为 Go 中的函数均可以看作闭包,这导致了很多人对函数相等有不同的理解。有些人认为两个函数的底层指针相等即相等,有些人认为两者内部的代码实现相等即相等,有些人认为两个函数在相同的输入下必须总是产生相同的输出才相等。 因为这些看法上的分歧,Go 干脆禁止 slice/map/function 值的比较。 |
4
liulaomo 2019-04-26 10:26:38 +08:00
|
5
peanuts7660 OP |