Go中与Python的"is"运算符相对应的是什么?

3

如何确定 Go 中的两个变量是否引用同一实例?更具体地说,一个变量的值发生改变时,另一个变量的值也会受到影响。

进一步明确问题:如何确定两个变量是否满足 CPython 中的“is”运算符:

a is b

2
这个问题可以有不同的解释。Go 有很多情况下,一个类型可能包含指向其他数据的指针或内部引用。您是否对特定情况感兴趣? - Sonia
3个回答

4

编辑:我不确定你想要什么。如果是关于变量的相等性或变量值的身份识别。这个答案是针对第二个问题(“2个变量引用相同的值实例”)。如果我误解了,我会删除这个答案。

== 是你想要的,我想。

如果a和b的类型是指针,那么a==b意味着a和b是指向相同值的指针。

以下程序输出false

package main

import "fmt"

type test struct {
    a int
}

func main() {

    b := &test{2}
    c := &test{2}
    fmt.Println(c == b)

}

虽然这会打印出true

    b := &test{2}
    c := b
    fmt.Println(c == b)
是一个充分条件,可以使得改变会导致的改变。

这对于像接口、切片、映射等引用类型是否有效? - Matt Joiner

3
在Python中,所有的值都是对象的引用(即指针)。你永远不能得到一个对象本身作为值。'is'运算符比较两个值,这些值是指针,判断它们是否相等;而'=='运算符比较两个指针所指向的对象是否相等。
在Go语言中,情况稍微复杂一些。Go有指针和其他非指针类型(布尔型、数字类型、字符串、数组、片段、结构体、函数、接口、映射、通道)。对于非指针类型来说,请求指针相等没有意义。(这意味着什么?会有什么收获吗?)
因此,为了让Go与Python的情况相当,我们将所有的值都放在指针后面,因此所有变量都是指针。 (在许多Go库中存在一个“New”函数的约定,它创建指针类型; 方法也操作指针类型,因此与该约定兼容。)然后(如果a和b是指针),Go中的'a == b'将比较两个指针的指针相等性;如果可比较,则可以使用'*a == *b'比较底层的值。
Go还具有几种非指针引用类型:slices、maps、functions和channels。通道可以使用“==”进行比较,判断它们是否是相同的通道。但是,片段、映射和函数不能进行比较;尽管可以使用反射来完成比较。

编译器似乎有一些优化来消除重复的分配,因此如果您在相邻的代码行中完全相同地分配两个结构体,则编译器实际上可以给您两个指向相同内存的指针(只有在您不修改它们时才可能)。这破坏了我的一个测试。此外,一些测试库似乎将指针比较为底层值(testify),因此assert.Equal(p1,p2)与assert.True(p1 == p2)不同,这也破坏了相同的测试... - Eloff

0

对于非接口和非函数类型,可以比较指针以检查它们是否相等。然而,非指针类型无法共享实例。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接