gpt4 book ai didi

go - 如何在 Go 中定义接受任意数量参数的函数类型?

转载 作者:IT王子 更新时间:2023-10-29 01:12:31 26 4
gpt4 key购买 nike

我尝试编写一个函数,它接受任何其他函数并围绕它包装一个新函数。到目前为止,这是我尝试过的:

package main

import (
"fmt"
)

func protect (unprotected func (...interface{})) (func (...interface{})) {
return func (args ...interface{}) {
fmt.Println ("protected");
unprotected (args...);
};
}

func main () {
a := func () {
fmt.Println ("unprotected");
};
b := protect (a);
b ();
}

编译时出现错误:

cannot use a (type func()) as type func(...interface { }) in function argument

为什么没有参数的函数与参数数量可变的函数不兼容?我该怎么做才能使它们兼容?

更新: protected 功能应该与原始功能兼容:

func take_func_int_int (f func (x int) (y int)) (int) {
return f (1)
}

func main () {

a := func (x int) (y int) {
return 2 * x
}
b := protect (a)

take_func_int_int (a)
take_func_int_int (b)
}

最佳答案

Go 中的类型非常具体。你可以试试

a := func(_ ...interface{}) {
fmt.Println("unprotected")
}

func (...interface{}) 并不意味着“任何函数接受任意数量的任何类型的参数”,它意味着“只有一个函数接受可变数量的接口(interface){ } 参数”

除了 func(...interface{}),您还可以只使用 interface{}reflect 包。参见 http://github.com/hoisie/web.go举个例子。

编辑:具体来说,这个:

package main

import (
"fmt"
"reflect"
)

func protect(oldfunc interface{}) (func (...interface{})) {
if reflect.TypeOf(oldfunc).Kind() != reflect.Func {
panic("protected item is not a function")
}
return func (args ...interface{}) {
fmt.Println("Protected")
vargs := make([]reflect.Value, len(args))
for n, v := range args {
vargs[n] = reflect.ValueOf(v)
}
reflect.ValueOf(oldfunc).Call(vargs)
}
}

func main() {
a := func() {
fmt.Println("unprotected")
}
b := func(s string) {
fmt.Println(s)
}
c := protect(a)
d := protect(b)
c()
d("hello")
}

输出是

Protected
unprotected
Protected
hello

编辑:回答更新

就像我上面说的,Go 中的类型非常具体。 protect 函数返回类型 func(...interface{})永远 可分配给 func(int)int。我认为您可能过度设计了您的问题或误解了它。但是,这里有一个非常不鼓励的代码片段,它可以让它工作。

首先将保护更改为也返回值:

func protect(oldfunc interface{}) (func (...interface{}) []interface{}) {
if reflect.TypeOf(oldfunc).Kind() != reflect.Func {
panic("protected item is not a function")
}
return func (args ...interface{}) []interface{} {
fmt.Println("Protected")
vargs := make([]reflect.Value, len(args))
for n, v := range args {
vargs[n] = reflect.ValueOf(v)
}
ret_vals := reflect.ValueOf(oldfunc).Call(vargs)
to_return := make([]interface{}, len(ret_vals))
for n, v := range ret_vals {
to_return[n] = v.Interface()
}
return to_return
}
}

然后做一个转换函数:

func convert(f func(...interface{}) (func(int) int) {
return func(x int) int {
r := f(x)
return r[0].(int)
}
}

那么你的电话看起来像

take_func_int_int(convert(b))

但我保证这不是您真正想要做的。

退后一步,尝试重新解决问题。在这些示例中,我已经完全扼杀了类型安全。你想要完成什么?

关于go - 如何在 Go 中定义接受任意数量参数的函数类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6047478/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com