Как мне преобразовать метод go в func? - PullRequest
4 голосов
/ 31 марта 2012

У меня есть функция уровня пакета (Frob), которая принимает функцию в качестве аргумента. В качестве аргумента функции я хочу передать метод (FrobMethod) с конкретным экземпляром структуры в качестве получателя (myFrob).

Единственный способ, который я нашел для достижения этой цели, это использовать func литерал / замыкание, которое захватывает целевую структуру. Это требует повторения подписи и аргументов функции, что кажется слишком многословным. Есть ли лучший способ?

package main

import "fmt"

func Frob( frobber func( int ) ( string ) ) {
    fmt.Printf( "Frob %s\n", frobber( 42 ) )
}

type MyFrob struct {
    Prefix string
}

func ( m MyFrob ) FrobMethod( n int ) ( string ) {
    return fmt.Sprintf( "%s %d", m.Prefix, n )
}

func main() {

    myFrob := MyFrob { Prefix: "Hello" }

    // C# allows something like this:
    //
    //Frob( myFrob.FrobMethod )

    Frob( func ( n int ) ( string ) {
        return myFrob.FrobMethod( n )
    } )
}

... реальным примером этого является HandleFunc в net / http.

Ответы [ 3 ]

4 голосов
/ 31 марта 2012

На мой взгляд, idiomatic Go должен использовать интерфейс вместо функции в этом случае:

package main

import "fmt"

type Frobber interface {
    FrobMethod(int) string
}

func Frob(frobber Frobber) {
    fmt.Printf("Frob %s\n", frobber.FrobMethod(42))
}

type MyFrob struct {
    Prefix string
}

func (m MyFrob) FrobMethod(n int) string {
    return fmt.Sprintf("%s %d", m.Prefix, n)
}

func main() {
    myFrob := MyFrob{Prefix: "Hello"}
    Frob(myFrob)
}

Функция HandleFunc в net/http является оболочкой для функции Handle, которая принимает аргумент интерфейса.

1 голос
/ 31 марта 2012

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

package main

import "fmt"

type Frobber interface {
    Frob(int) string
}

type MyFrob struct {
    Prefix string
}

func (m MyFrob) Frob(n int) string {
    return fmt.Sprintf("%s %d", m.Prefix, n)
}

func Frob(f Frobber) {
    fmt.Printf("Frob %s\n", f.Frob(42))
}

func main() {
    myFrob := MyFrob {Prefix: "Hello"}
    Frob(myFrob)
}

В объектно-ориентированном языке вы быбыть в состоянии просто передать метод, но Go не OO.Вы должны начать свой ум с самого начала и не пытаться писать код, как это было бы на других языках.У меня та же проблема с Python.

Кстати, я люблю Go и активно пытаюсь улучшить свои навыки с помощью этого инструмента в своем поясе инструментов.Отвечая на @Jeremy в комментариях, я только заявляю, что Go не является OO, потому что команда Go не поддерживает его так, и его чаще называют процедурным, и, имея смесь элементов из других языковкоторые сами считаются OO

0 голосов
/ 10 апреля 2013

Начиная с версии 1.1, ссылка на метод в стиле C # работает:

Frob( myFrob.FrobMethod )

См. Раздел Выражения метода в спецификации языка Go.

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