英文:
Is it possible to bind a method at runtime?
问题
我有以下的结构:
type Foo struct {
Bar func(foo *Foo) bool
}
因为Bar
实际上不是一个方法,它接受Foo
作为参数(类似于Python中的绑定方法的self
)。然而,如果有一种简单的方法,我会将它绑定到结构体作为一个方法。我怀疑我可以使用反射来实现,但我想保持它简单。有没有一种将函数绑定到结构体的技巧?你会怎么做?
编辑:我将添加一个具体的例子来说明我在做什么。
type Route struct {
Matcher func(route *Route, r *http.Request) bool
}
Route接受一个自定义的Matcher
函数。如果未设置,则在注册路由时设置默认的匹配函数:
func (mux *ServeMux) HandleRoute(r Route) {
// ...
// 设置默认的匹配函数。
if r.Matcher == nil {
r.Matcher = mux.RouteMatcher
}
// ...
}
然后,该函数用于进行匹配:
func (mux *ServeMux) Match(r *http.Request) Route {
// ...
if route.Matcher(&route, r) {
...
}
...
}
该函数并未绑定到路由上。我的问题是,这种设置自定义可调用对象的方式是否合理/符合惯例,或者是否有一种将函数“绑定”到结构体作为方法的技巧。
英文:
I have the following construct:
type Foo struct {
Bar func(foo *Foo) bool
}
Because Bar
is not really a method, it accepts Foo
as parameter (like self
in Python's bound methods). I'd however bind it to the struct as a method if there was an easy way. I suspect I could using reflection, but I want to keep it trivial. Is there a trick to bind a function to a struct? How would you do it?
Edit: I'll add a concrete example of what I'm doing.
type Route struct {
Matcher func(route *Route, r *http.Request) bool
}
Route accepts a custom Matcher
function. If not set, a default matcher function is set when the route is registered:
func (mux *ServeMux) HandleRoute(r Route) {
// ...
// Set default matcher.
if r.Matcher == nil {
r.Matcher = mux.RouteMatcher
}
// ...
}
Then that function is used to do a matching:
func (mux *ServeMux) Match(r *http.Request) Route {
// ...
if route.Matcher(&route, r) {
...
}
...
}
The function is not bound to the route. My question is if this is a reasonable/idiomatic way to set a custom callable, or if there is a trick to make the function "bound" to the struct as a method.
答案1
得分: 2
你没有解释你想要实现什么。这个有什么问题吗?
package main
import "fmt"
type Foo struct{}
func (f *Foo) Bar() bool {
return true
}
func main() {
var f Foo
fmt.Println(f.Bar())
}
输出:
true
你想要做类似这样的事情吗?
package main
import "fmt"
type BarFunc func(foo *Foo) bool
type Foo struct {
BarFunc
}
func (f *Foo) Bar() bool {
return f.BarFunc(f)
}
func UserBarFunc(foo *Foo) bool { return true }
func main() {
var f Foo
f.BarFunc = UserBarFunc
fmt.Println(f.Bar())
}
输出:
true
英文:
You don't explain what you are trying to accomplish. What is wrong with this?
package main
import "fmt"
type Foo struct{}
func (f *Foo) Bar() bool {
return true
}
func main() {
var f Foo
fmt.Println(f.Bar())
}
Output:
true
Are you trying to do something like this?
package main
import "fmt"
type BarFunc func(foo *Foo) bool
type Foo struct {
BarFunc
}
func (f *Foo) Bar() bool {
return f.BarFunc(f)
}
func UserBarFunc(foo *Foo) bool { return true }
func main() {
var f Foo
f.BarFunc = UserBarFunc
fmt.Println(f.Bar())
}
Output:
true
答案2
得分: 2
在运行时绑定新方法是不可能的。编译器需要在编译时知道类型有哪些方法。考虑以下代码:
package main
import "rand"
type Foo struct {}
type Bar interface {
Baz()
}
func main() {
if rand.Intn(2) != 0 {
// 在运行时绑定方法Baz到Foo的代码
}
var f Foo
// 这段代码能编译通过吗?这取决于上面的if语句是否执行,而这只能在运行时知道。
f.Baz()
// 同样的情况。编译器无法知道f是否有一个方法Baz。
var b Bar = f
}
你的示例代码看起来是实现你想要的方式。PeterSO的答案提供了另一种方式,使函数看起来更像是一个普通的方法。
英文:
It's not possible to bind a new method at runtime. The compiler needs to know what methods a type has at compile time. Consider this code:
package main
import "rand"
type Foo struct {}
type Bar interface {
Baz()
}
func main() {
if rand.Intn(2) != 0 {
// code to bind method Baz to Foo at runtime
}
var f Foo
// Should this compile? It depends on whether or not the if
// statement above ran, which can only be known at runtime.
f.Baz()
// Same here. The compiler can't know whether or not f has
// a method Baz.
var b Bar = f
}
Your example code looks like a reasonable way to do what you want. PeterSO's answer presents another way to do it that makes the function look more like a regular method.
答案3
得分: 0
你可以创建一个带有所需名称(Bar
)的辅助方法,在运行时选择并调用所需的函数,这样怎么样?
英文:
How about you create a helper method with the desired name (Bar
) that chooses and calls the desired function at runtime?
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论