V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
peanuts7660
V2EX  ›  Go 编程语言

请教一个 Golang 中引用类型进行比较的问题。

  •  
  •   peanuts7660 · 2019-04-25 20:27:23 +08:00 · 2823 次点击
    这是一个创建于 2047 天前的主题,其中的信息可能已经有所发展或是发生改变。

    请教一个 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 没有呢???

    5 条回复    2019-04-26 11:17:43 +08:00
    LANB0
        1
    LANB0  
       2019-04-25 20:37:22 +08:00
    C++的思维看,大概是 channel 实现了对==的重载,而 slice 和 map 没实现
    reus
        2
    reus  
       2019-04-25 21:13:06 +08:00
    go 的 = 操作,就是简单的内存比较

    slice 的内存不连续,slice header 和 data 分开放的,所以不能比较

    map 的内存不连续,bucket 是分开放的,所以不能比较

    chan 的内存是连续的,就一个对象,所以可以比较
    liulaomo
        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 值的比较。
    liulaomo
        4
    liulaomo  
       2019-04-26 10:26:38 +08:00
    peanuts7660
        5
    peanuts7660  
    OP
       2019-04-26 11:17:43 +08:00
    @LANB0 @liulaomo @reus 非常感谢你们的回答,获益匪浅,谢谢。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3459 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 11:36 · PVG 19:36 · LAX 03:36 · JFK 06:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.