英文:
Writing a generic binder in Go
问题
考虑以下函数——第二个参数的绑定器。
func bindSecond(value interface{}, f func(a interface{}, b interface{})) func(c interface{}) {
return func(arg interface{}) {
f(arg, value)
}
}
考虑一个函数
func f(x int, y int) {}
当尝试将其作为绑定器的参数时,Go编译器报错:
cannot use f (type func(int, int)) as type func(interface {}, interface {}) in argument to bindSecond.
请问你能否为我提供在Go中实现绑定器的正确方法?
英文:
Consider the following function -- a binder of the second argument.
func bindSecond(value interface{}, f func(a interface{}, b interface{})) func (c interface{}) {
return func(arg interface{}) {
f(arg, value)
}
}
Consider a function
func f(x int, y int) {}
When trying to use it as a parameter in binder, go compiler says:
cannot use f (type func(int, int)) as type func(interface {}, interface {}) in argument to bindSecond.
Could you please suggest me the proper way of implementing binders in go (golang)?
答案1
得分: 4
将interface{}
替换为int
,它就会工作。
或者更重要的是,尝试使用Go提供的功能来找到解决方案,而不是试图从不同的范式中强行解决问题。
英文:
Replace interface{}
with int
and it will work.
Or, more to the point, try to find a solution to your original problem using the features Go provides, instead of trying to force a solution from a different paradigm.
答案2
得分: 4
我明白你想做什么,一些模板对吧?但是这种方式行不通。你的 f func(a interface{}, b interface{})
参数不是一个接口,所以它必须是匹配的类型。你可以通过传递 f interface{}
并使用 reflect
包来实现你想要的效果。
这是一个简单的示例:
package main
import (
"fmt"
"reflect"
)
func bindSecond(value interface{}, f interface{}) func(c interface{}) {
return func(arg interface{}) {
reflect.ValueOf(f).Call([]reflect.Value{reflect.ValueOf(arg), reflect.ValueOf(value)})
}
}
func main() {
sum := func(x int, y int) { fmt.Println(x + y) }
inc := bindSecond(1, sum)
inc(10)
}
// 输出 11
这样是可行的,但不太美观。如果发生任何意外情况,例如 f
不可调用或不接受恰好两个参数,或者你向 inc
传递了错误的类型,它会在运行时引发 panic。编译器将无法再帮助你。
英文:
I see what you're trying to do, some templates, right? But this is not going to work this way. Your f func(a interface{}, b interface{})
argument is not an interface, so it must be of the matching type. You could achieve what you want by passing f interface{}
and then manipulate it with reflect
package.
Some naive example:
package main
import (
"fmt"
"reflect"
)
func bindSecond(value interface{}, f interface{}) func(c interface{}) {
return func(arg interface{}) {
reflect.ValueOf(f).Call([]reflect.Value{reflect.ValueOf(arg), reflect.ValueOf(value)})
}
}
func main() {
sum := func(x int, y int) { fmt.Println(x + y) }
inc := bindSecond(1, sum)
inc(10)
}
// Prints 11
Doable, but not very pretty. And panics in runtime if anything unexpected happens, for example f
is not callable and doesn't take exactly two arguments. Or you pass a wrong type to inc
. Complier won't help you anymore.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论