Как передать по адресу функцию, которая принимает интерфейс

У меня есть интерфейс Character, определенный как:

type Character interface {
    SomeFunction()
}

И структура Player определена как:

type Player struct{}

func (r *Player) SomeFunction() { }
// Some fields and other functions....

Предположим, у меня есть функция, определенная как

func TakeInterface(characterValue Character) {
     // Do something
}

Загвоздка в том, что я хочу передать characterValue как Player по адресу, чтобы изменения, внесенные в него, были внесены в Player, переданный вызывающим абонентом. В Java и C++ это легко, но я не могу понять это в Голанге. Я пробовал что-то вроде,

func TakeInterface(characterValue &Character) {
    // Do something that changes characterValue
}

а затем передать указатель Player, но затем я получаю сообщение об ошибке *Character.Character is pointer to interface, not interface, когда пытаюсь передать адрес.

Как мне передать Player по адресу функции, которая принимает указатель Character/Character? Я искал вокруг, но безуспешно. Спасибо!


person cepiolot    schedule 12.12.2017    source источник
comment
Заставить SomeFuncion принимать приемник указателя?   -  person Volker    schedule 12.12.2017
comment
@Volker в моей реализации SomeFunction() уже принимала приемник указателя, соответствующим образом обновила вопрос, спасибо, что заметили.   -  person cepiolot    schedule 12.12.2017
comment
Возьмите адрес Player и передайте его TakeInterface. См. play.golang.org/p/oZKuFC0z1l.   -  person Cerise Limón    schedule 12.12.2017
comment
Как мне передать Player по адресу функции, которая принимает указатель Character/Character? Вы просто делаете не делаете этого! Вы никогда (за исключением того, что вам нужно, а вы этого не делаете!) передаете указатели на интерфейсы. Вы передаете значения интерфейсам. Это возможно, если тип реализует интерфейс. Некоторые типы реализуют интерфейсы только для приемников указателей.   -  person Volker    schedule 12.12.2017
comment
@Volker, но Player - это не интерфейс. То, что они описывают, совершенно нормально: передача указателя на объект функции, которая принимает интерфейс, который удовлетворяет объект.   -  person Adrian    schedule 12.12.2017
comment
Я не говорю о плеере. Вы спросили об указателе Character/Character, и это неверно.   -  person Volker    schedule 12.12.2017


Ответы (1)


Вы тестировали свой код? Я предполагаю, что нет, потому что это работает так, как вы ожидаете. Просто передайте указатель на игрока при вызове функции.

func main() {
    p := new(Player)
    TakeInterface(p)
}

Or

func main() {
    p := Player{0}
    TakeInterface(&p)
}

В go вы можете использовать тип или указатель на тип в качестве аргумента функции, которая принимает интерфейс, потому что оба удовлетворяют интерфейсу. Вы можете сделать оба:

    var p1 Player
    p1.SomeFunction()
    var p2 *Player
    p2.SomeFunction()

Вы должны пройти тур по go: https://tour.golang.org/methods/10

Вот весь код: https://play.golang.org/p/iQIChLCziG

person Topo    schedule 12.12.2017
comment
Чтобы ответить на ваш вопрос, я протестировал свой код, но мне не пришло в голову, что вы можете передать значение или указатель на функцию, которая принимает значение интерфейса. Я продолжал пытаться передать указатель игрока функции, принимающей указатель на символ. Я огляделся, но не нашел такого ответа, мой плохой. Спасибо за Ваш ответ. - person cepiolot; 12.12.2017
comment
См. также мой ответ здесь немного более подробную информацию об указателях, значениях и интерфейсах и о том, как все это работает. - person Kaedys; 13.12.2017