donglin7979
2018-10-11 12:08
浏览 124
已采纳

有没有一种方法可以定义一个可以在Golang中运行任何回调函数的函数?

I want to define a function to run a callback function, and the callback function will be uncertain, such as args or returns both are uncertain.

I try this:

package main

import (
    "fmt"
)

func F(callback func(args ...interface{}) interface{}, args ...interface{}) {
    rev := callback(args...)
    fmt.Println(rev)
}

func CB1() {
    fmt.Println("CB1 called")
}

func CB2() bool {
    fmt.Println("CB2 called")
    return false
}

func CB3(s string) {
    fmt.Println("CB3 called")
}

func CB4(s string) bool {
    fmt.Println("CB4 called")
    return false
}

func main() {
    F(CB1)
    F(CB2)
    F(CB3, "xxx")
    F(CB4, "yyy")
}

errors:

./play.go:31:3: cannot use CB1 (type func()) as type func(...interface {}) interface {} in argument to F
./play.go:32:3: cannot use CB2 (type func() bool) as type func(...interface {}) interface {} in argument to F
./play.go:33:3: cannot use CB3 (type func(string)) as type func(...interface {}) interface {} in argument to F
./play.go:34:3: cannot use CB4 (type func(string) bool) as type func(...interface {}) interface {} in argument to F

图片转代码服务由CSDN问答提供 功能建议

我想定义一个函数来运行回调函数,并且该回调函数将是不确定的,例如args或

我尝试这样做:

 包main 
 
import(
“ fmt” 
)\  n 
func F(回调函数(args ... interface {})interface {},args ... interface {}){
 rev:= callback(args ...)
 fmt.Println(rev)\  n} 
 
func CB1(){
 fmt.Println(“ CB1被称为”)
} 
 
func CB2()bool {
 fmt.Println(“ CB2被称为”)
返回false 
  } 
 
func CB3(s字符串){
 fmt.Println(“ CB3被称为”)
} 
 
func CB4(s字符串)bool {
 fmt.Println(“ CB4被称为”)
返回 false 
} 
 
func main(){
 F(CB1)
 F(CB2)
 F(CB3,“ xxx”)
 F(CB4,“ yyy”)
} 
 <  / code>  
 
 

错误:

 。/play.go:31:3:无法将CB1(类型为func())用作 在F 
./play.go:32:3的参数中键入func(... interface {})interface {}:不能将CB2(func()bool类型)用作func(... interface {}接口) 接口{} 在F 
./play.go:33:3的参数中:不能在F 
./play的参数中使用CB3(func(string)类型)作为func(... interface {})interface {}类型。 转到:34:3:在F 
   
 
  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • donxbje866688 2018-10-11 12:20
    已采纳

    You can, but since Go does not support generics, you have to define callback to be of type interface{}.

    To call a function value stored in callback, you may use reflection, namely the Value.Call() method.

    This is how it would look like:

    func F(callback interface{}, args ...interface{}) {
        v := reflect.ValueOf(callback)
        if v.Kind() != reflect.Func {
            panic("not a function")
        }
        vargs := make([]reflect.Value, len(args))
        for i, arg := range args {
            vargs[i] = reflect.ValueOf(arg)
        }
    
        vrets := v.Call(vargs)
    
        fmt.Print("\tReturn values: ")
        for _, vret := range vrets {
            fmt.Print(vret)
        }
        fmt.Println()
    }
    

    With this, the output of your app will be (try it on the Go Playground):

    CB1 called
        Return values: 
    CB2 called
        Return values: false
    CB3 called
        Return values: 
    CB4 called
        Return values: false
    
    已采纳该答案
    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题