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

如何比较 Go 中的 2 个函数?

如何比较 Go 中的 2 个函数?

Go
ITMISS 2021-12-07 14:48:56
例如,我有要比较的函数列表:http://play.golang.org/p/_rCys6rynftype Action func(foo string)type Handler struct {  Get Action  Post Action}var routes map[string]Handlerfunc Undefined(foo string) {}func Defined(foo string) {}func init() {  routes = map[string]Handler{    `/`: Handler{Defined,Undefined},  }}func main() {  for _, handler := range routes {    if handler.Post != Undefined {       // do something    } // invalid operation: (func(string))(handler.Post) != Undefined (func can only be compared to nil)    if &handler.Post != &Undefined {       // do something     } // cannot take the address of Undefined    // invalid operation: &handler.Post != &Undefined (mismatched types *Action and *func(string))  }}比较两个函数是否相同的正确方法是什么?
查看完整描述

3 回答

?
精慕HU

TA贡献1845条经验 获得超8个赞

在继续之前:您应该重构而不是比较函数值地址。


规范:比较运算符:


切片、映射和函数值不可比较。但是,作为特殊情况,切片、映射或函数值可以与预先声明的标识符进行比较nil。


函数值不具有可比性。您可以做的是比较函数值的地址是否相同(不是保存函数值的变量的地址,而是函数值本身)。


您不能获取 function 的地址,但是如果您将其与fmt包一起打印,则会打印其地址。所以你可以使用fmt.Sprintf()来获取一个函数值的地址。


请参阅此示例(基于您的代码):


hand := &Handler{Undefined, Defined}

p1 := fmt.Sprintf("%v", Undefined)

p2 := fmt.Sprintf("%v", hand.Get)

fmt.Println("Expecting true:", p1 == p2)


fmt.Println("Expecting false:", fmt.Sprintf("%v", Defined) == fmt.Sprintf("%v", hand.Get))

fmt.Println("Expecting true:", fmt.Sprintf("%v", Defined) == fmt.Sprintf("%v", hand.Post))

输出(在Go Playground上试试):


Expecting true: true

Expecting false: false

Expecting true: true

另一种选择是用于reflect.Value.Pointer()获取函数值的地址,这正是fmt包的作用fmt/print.go:


func (p *pp) fmtPointer(value reflect.Value, verb rune) {

    // ...

    case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice,

            reflect.UnsafePointer:

        u = value.Pointer()

    // ...

}

但是您应该重构而不是比较函数值地址。


查看完整回答
反对 回复 2021-12-07
?
30秒到达战场

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

没关系,找到答案:

runtime.FuncForPC(reflect.ValueOf(handler.Post).Pointer()).Name() != 
   runtime.FuncForPC(reflect.ValueOf(Undefined).Pointer()).Name()


查看完整回答
反对 回复 2021-12-07
?
墨色风雨

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

你不能比较功能。它需要存储到一个变量中,并将其作为指针引用。

http://play.golang.org/p/sflsjjCHN5


查看完整回答
反对 回复 2021-12-07
  • 3 回答
  • 0 关注
  • 372 浏览
慕课专栏
更多

添加回答

举报

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