为了账号安全,请及时绑定邮箱和手机立即绑定

如何在最新的Go周刊中比较两个函数的指针相等性?

如何在最新的Go周刊中比较两个函数的指针相等性?

Go
杨魅力 2021-05-02 08:09:45
在Go中,是否可以比较两个非nil函数指针以测试是否相等?我的平等标准是指针平等。如果不是,是否有任何特定的原因为什么不允许指针相等?到目前为止,如果我尝试以简单的方式执行此操作:package mainimport "fmt"func SomeFun() {}func main() {    fmt.Println(SomeFun == SomeFun)}我懂了./func-pointers.go:12: invalid operation: SomeFun == SomeFun (func can only be compared to nil)据我了解,这种行为是最近才引入的。我已经使用反射包找到了答案;但是Atom在下面暗示这实际上会产生未定义的行为。有关更多信息和可能的替代解决方案,请参见Atom的帖子。package mainimport "fmt"import "reflect"func SomeFun() { }func AnotherFun() { }func main() {    sf1 := reflect.ValueOf(SomeFun)    sf2 := reflect.ValueOf(SomeFun)    fmt.Println(sf1.Pointer() == sf2.Pointer())    af1 := reflect.ValueOf(AnotherFun)    fmt.Println(sf1.Pointer() == af1.Pointer())}输出:truefalse
查看完整描述

2 回答

?
慕丝7291255

TA贡献1859条经验 获得超6个赞

注意,平等和同一性之间是有区别的。Go1中的运算符==和和!=正在比较等效值(比较通道时除外),而不是标识。因为这些运算符试图不混和平等和同一性,所以Go1在这方面比Go1之前更加一致。


函数相等与函数身份不同。


对于不允许的原因之一==,并!=在功能类型是性能。例如,以下关闭未使用其环境中的任何变量:


f := func(){fmt.Println("foo")}

不允许进行功能比较,使编译器可以为闭包生成单个实现,而不是要求运行时创建新的闭包(在运行时)。因此,从性能的角度来看,不允许进行功能比较的决定是一个不错的决定。


关于使用reflect包确定功能标识,类似


func SomeFun()    {}

func AnotherFun() {}


func main() {

    sf1 := reflect.ValueOf(SomeFun)

    sf2 := reflect.ValueOf(SomeFun)

    fmt.Println(sf1.Pointer() == sf2.Pointer())  // Prints true


    af1 := reflect.ValueOf(AnotherFun)

    fmt.Println(sf1.Pointer() == af1.Pointer())  // Prints false

}

依赖未定义的行为。无法保证程序将打印什么。编译器可能会决定将其合并SomeFun并合并AnotherFun为单个实现,在这种情况下,第二个print语句将为print true。实际上,绝对不能保证第一个print语句将被打印true(在其他Go1编译器和运行时下,它可能会打印false)。


原始问题的正确答案是:


package main


import "fmt"


func F1() {}

func F2() {}


var F1_ID = F1  // Create a *unique* variable for F1

var F2_ID = F2  // Create a *unique* variable for F2


func main() {

    f1 := &F1_ID  // Take the address of F1_ID

    f2 := &F2_ID  // Take the address of F2_ID


    // Compare pointers

    fmt.Println(f1 == f1)  // Prints true

    fmt.Println(f1 == f2)  // Prints false

}


查看完整回答
反对 回复 2021-05-10
  • 2 回答
  • 0 关注
  • 285 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信