Kok*_*zzu 4 function-pointers function go
例如,我有我要比较的函数列表:
http://play.golang.org/p/_rCys6rynf
type Action func(foo string)
type Handler struct {
Get Action
Post Action
}
var routes map[string]Handler
func 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))
}
}
Run Code Online (Sandbox Code Playgroud)
如果两个函数相同,比较的正确方法是什么?
icz*_*cza 12
在进一步说明之前:你应该重构而不是比较函数值地址.
切片,贴图和函数值无法比较.然而,作为特殊情况,可以将切片,映射或函数值与预先声明的标识符进行比较
nil.
功能值无法比较.您可以做的是比较函数值的地址是否相同(不是包含函数值的变量的地址,而是函数值本身).
您无法获取函数的地址,但如果使用该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))
Run Code Online (Sandbox Code Playgroud)
输出(在Go Playground上试试):
Expecting true: true
Expecting false: false
Expecting true: true
Run Code Online (Sandbox Code Playgroud)
另一种选择是使用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()
// ...
}
Run Code Online (Sandbox Code Playgroud)
但是你应该重构而不是比较函数值地址.
没关系,找到答案:
runtime.FuncForPC(reflect.ValueOf(handler.Post).Pointer()).Name() !=
runtime.FuncForPC(reflect.ValueOf(Undefined).Pointer()).Name()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2878 次 |
| 最近记录: |