-3

I have a Character interface defined like:

type Character interface {
    SomeFunction()
}

And a Player struct defined like:

type Player struct{}

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

Suppose I have a function defined as

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

The catch is, I want to pass in characterValue as a Player by address so that changes made to it will be made to the Player the caller passed in. In Java and C++, this is easy, but I can't seem to figure it out in Golang. I've tried something like,

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

and then passing in a Player pointer, but then I get the error *Character.Character is pointer to interface, not interface when I try to pass in an address.

How do I go about passing a Player by address to a function that takes a Character/Character pointer? I've been looking around but with no success. Thanks!

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
cepiolot
  • 71
  • 9
  • Make SomeFuncion take a pointer reciever? – Volker Dec 12 '17 at 04:54
  • @Volker in my implementation, SomeFunction() was already taking a pointer receiver, updated the question accordingly, thanks for noticing. – cepiolot Dec 12 '17 at 04:57
  • 1
    Take the address of a Player and pass it to TakeInterface. See https://play.golang.org/p/oZKuFC0z1l . – Charlie Tumahai Dec 12 '17 at 05:30
  • "How do I go about passing a Player by address to a function that takes a Character/Character pointer?" You simply *do* *not* *do* *this*! You never (except you need to and you do not!) pass pointers to interfaces. You pass values to interfaces. This is possible if the type implements the interface. Some type implement interfaces only for pointer receivers. – Volker Dec 12 '17 at 08:32
  • @Volker but Player isn't an interface. What they're describing is completely normal: passing a pointer to an object to a function that takes an interface that the object satisfies. – Adrian Dec 12 '17 at 14:56
  • I'm not talking about Player. You asked about "a Character/Character pointer" and that is _wrong_. – Volker Dec 12 '17 at 20:22

1 Answers1

2

Have you tested your code? I'm guessing no, because it works the way you expect it to work. Just pass a pointer to a player when calling the function.

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

Or

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

In go you can use a type or a pointer to a type as an argument to a function that takes an interface because both satisfy the interface. You can do both:

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

You should do the tour of go: https://tour.golang.org/methods/10

Here is the whole code: https://play.golang.org/p/iQIChLCziG

Topo
  • 4,783
  • 9
  • 48
  • 70
  • To answer your question, I tested my code but it didn't occur to me that you could pass a value or a pointer to a function that takes an interface value. I kept trying to pass a player pointer to a function taking a character pointer. I looked around but didn't find an answer like this, my bad. Thanks for your answer. – cepiolot Dec 12 '17 at 18:51
  • See also my answer [here](https://stackoverflow.com/questions/44370277/type-is-pointer-to-interface-not-interface-confusion/44372954#44372954) for a bit more details on pointers versus values and interfaces and how that all functions. – Kaedys Dec 12 '17 at 22:20