Есть ли способ определить функцию, можно запустить любую функцию обратного вызова в Golang? - PullRequest
0 голосов
/ 11 октября 2018

Я хочу определить функцию для запуска функции обратного вызова, и функция обратного вызова будет неопределенной, например, аргументы или возвраты будут неопределенными.

Я пытаюсь это:

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

ошибки:

./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

1 Ответ

0 голосов
/ 11 октября 2018

Вы можете, но так как Go не поддерживает генерики, вы должны определить callback для типа interface{}.

Чтобы вызвать значение функции, хранящееся в callback, вы можете использовать отражениеа именно метод Value.Call().

Вот как это будет выглядеть:

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

При этом вывод вашего приложения будет (попробуйтена игровой площадке Go ):

CB1 called
    Return values: 
CB2 called
    Return values: false
CB3 called
    Return values: 
CB4 called
    Return values: false
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...