&引用;方法需要指针接收器“;in-Go编程语言

&引用;方法需要指针接收器“;in-Go编程语言,go,Go,我刚刚看了一个Go编程语言的演示,我想我应该试着写几行。在我尝试在这种情况下使用界面之前,一切都很正常。我如何解决这个问题 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.P

我刚刚看了一个Go编程语言的演示,我想我应该试着写几行。在我尝试在这种情况下使用界面之前,一切都很正常。我如何解决这个问题

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)
}
我发现编译器错误:

prog.go:24: cannot use e (type entity) as type incer in function argument:
entity does not implement incer (inc method requires pointer receiver)
我想使用一个指针,这样inc()将影响函数外部的enity。我应该使用什么语法


/瑞奇

将其更改为:doSomething&e。func(e*entity)inc()仅满足*实体类型的incer接口。实体类型没有inc(),这就是您要传递给doSomething()的内容。

我认为这里有些混乱
inc
是类型为
*entity
的方法,而不是类型为
entity
(您可以直接在指针上调用值上的方法;通常不能直接在值上调用指针上的方法)。您可能会感到困惑的是,为什么您可以调用
e.inc()
,而不必执行
(&e.inc()
)。这是一个鲜为人知的特例,记录在语言规范的部分底部,它表示如果
x
是可寻址的,并且
&x
的方法集包含
m
,那么
x.m()
(&x.m()
的缩写。这适用于这种情况,因为
e
是一个变量,所以它是可寻址的;但其他表达方式可能无法寻址。但是,我建议您不要使用此快捷方式,因为它会造成混乱;它使您认为
e
符合接口
inter
,而它不符合。

@Ricky,更清楚一点:实际参数总是按值传递给方法,因此对于“accessor”方法,编译器在将e.foo()转换为(&e).foo()时没有问题,但“mutator”方法显然必须更改实际值,不是它们的本地方法副本,因此非引用类型的值必须使用指针传递给这些方法,并且编译器无法执行正在讨论的技巧。请参阅newacct中的“我应该在值或指针上定义方法吗?”:很好的解释。