Reputation: 3586
I just saw a presentation of the Go programming language and thought I'd try to write a few lines. Everything worked fine until I tried to use an interface in this situation. How do I solve this?
package main
import "fmt"
type entity float32
func (e *entity) inc() {
*e++
}
type incer interface {
inc()
}
func doSomething(i incer) {
i.inc()
}
func main() {
fmt.Println("Hello, 世界")
var e entity = 3
e.inc()
doSomething(e)
fmt.Println(e)
}
I get the compiler error:
prog.go:24: cannot use e (type entity) as type incer in function argument:
entity does not implement incer (inc method requires pointer receiver)
I want to use a pointer so that the inc() will affect the enity outside the function. What is the syntax I should use?
/Ricky
Upvotes: 18
Views: 11670
Reputation: 122518
I think there is some confusion here. inc
is a method of the type *entity
, and not of the type entity
(while you can call methods on values directly on pointers; you cannot generally call methods on pointers directly on values). What you may be confused about is why you could call e.inc()
, instead of having to do (&e).inc()
. This is a little-known special case documented at the bottom of the Calls section in the language specification, that says if x
is addressable, and &x
's method set contains m
, then x.m()
is shorthand for (&x).m()
. This applies to this case because e
is a variable, so it is addressable; but other expressions may not be addressable. I would recommend that you not use this shortcut, however, as it causes confusion; it makes you think that e
conforms to the interface inter
, while it does not.
Upvotes: 23
Reputation: 3563
Change it to: doSomething(&e). func (e *entity) inc() satisfies incer interface only for *entity type. There is no inc() for just entity type and that's what's you're passing to doSomething().
Upvotes: 4