Можно ли привязать метод во время выполнения? - PullRequest
2 голосов
/ 14 августа 2011

У меня есть следующая конструкция:

type Foo struct {
    Bar func(foo *Foo) bool
}

Поскольку Bar на самом деле не является методом, он принимает Foo в качестве параметра (как self в связанных методах Python). Однако я бы связал его со структурой как методом, если бы был простой способ. Я подозреваю, что мог бы использовать отражение, но я хочу, чтобы это было тривиально. Есть ли хитрость, чтобы связать функцию со структурой? Как бы вы это сделали?

Редактировать: я добавлю конкретный пример того, что я делаю.

type Route struct {
    Matcher func(route *Route, r *http.Request) bool
}

Маршрут принимает пользовательскую функцию Matcher. Если не установлено, функция соответствия по умолчанию устанавливается при регистрации маршрута:

func (mux *ServeMux) HandleRoute(r Route) {
    // ...

    // Set default matcher.
    if r.Matcher == nil {
        r.Matcher = mux.RouteMatcher
    }

    // ...
}

Затем эта функция используется для сопоставления:

func (mux *ServeMux) Match(r *http.Request) Route {
    // ...

    if route.Matcher(&route, r) {
        ...
    }

    ...
}

Функция не привязана к маршруту. Мой вопрос заключается в том, является ли это разумным / идиоматическим способом установки пользовательского вызываемого объекта, или если есть хитрость, чтобы сделать функцию "привязанной" к структуре как метод.

Ответы [ 3 ]

2 голосов
/ 15 августа 2011

Невозможно связать новый метод во время выполнения.Компилятор должен знать, какие методы имеет тип во время компиляции.Рассмотрим этот код:

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
}

Ваш пример кода выглядит как разумный способ сделать то, что вы хотите.Ответ PeterSO представляет еще один способ сделать это, чтобы функция выглядела как обычный метод.

2 голосов
/ 14 августа 2011

Вы не объясняете, чего пытаетесь достичь.Что с этим не так?

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
0 голосов
/ 15 августа 2011

Как насчет создания вспомогательного метода с нужным именем (Bar), который выбирает и вызывает нужную функцию во время выполнения?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...