How to compare 2 functions in Go?

对着背影说爱祢 提交于 2019-11-29 15:08:06

Before going further: you should refactor and not compare function value addresses.

Spec: Comparison operators:

Slice, map, and function values are not comparable. However, as a special case, a slice, map, or function value may be compared to the predeclared identifier nil.

Function values are not comparable. What you may do is compare if the addresses of the function values are the same (not the address of variables holding function values, but the function values themselves).

You can't take the address of a function, but if you print it with the fmt package, it prints its address. So you can use fmt.Sprintf() to get the address of a function value.

See this example (based on your code):

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))

Output (try it on the Go Playground):

Expecting true: true
Expecting false: false
Expecting true: true

Another option would be to use reflect.Value.Pointer() to get the address of the function values, this is exactly what the fmt package does: 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()
    // ...
}

But you should refactor and not compare function value addresses.

Nevermind, found the answer:

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

You can't compare function. It need to be stored into a variable instead and reference it as pointer.

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!