在Go编程语言中,“方法需要指针接收器”。

huangapple go评论85阅读模式
英文:

"method requires pointer receiver" in Go Programming Language

问题

我刚刚看了一份关于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()会影响函数外的entity。我应该使用什么语法?

英文:

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

答案1

得分: 22

我认为这里有一些混淆。inc*entity类型的方法,而不是entity类型的方法(尽管你可以直接在指针上调用值的方法,但通常不能直接在值上调用指针的方法)。你可能困惑的是为什么可以调用e.inc(),而不是必须使用(&e).inc()。这是一个鲜为人知的特殊情况,在语言规范的Calls部分底部有记录,它说如果x是可寻址的,并且&x的方法集包含m,那么x.m()(&x).m()的简写。这适用于这种情况,因为e是一个变量,所以它是可寻址的;但其他表达式可能不可寻址。然而,我建议你不要使用这个快捷方式,因为它会引起混淆;它让你认为e符合接口inter,但实际上并不符合。

英文:

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.

答案2

得分: 4

将其更改为:doSomething(&e)。func (e *entity) inc() 仅为 *entity 类型满足 incer 接口。对于仅为 entity 类型的 inc() 是不存在的,而这正是您传递给 doSomething() 的内容。

英文:

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().

huangapple
  • 本文由 发表于 2011年9月16日 06:47:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/7438323.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定