开发者

Is it possible to bind a method at runtime?

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.Match开发者_StackOverflow社区er(&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.


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


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.


How about you create a helper method with the desired name (Bar) that chooses and calls the desired function at runtime?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜