Golang方法接收器

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

Golang method receiver

问题

根据这个问题,Golang会生成type-receiver methodpoint-receiver method,这意味着下面的代码将正常工作,但值会意外地改变。

func (test *Test) modify() {
    test.a++
}

func main() {
    test := Test{10}
    fmt.Println(test)
    test.modify()
    fmt.Println(test)
}

我认为这对我来说是可以接受的。但是当这与接口混合使用时,问题就出现了。

type Modifiable interface {
    modify()
}

type Test struct {
    a int
}

func (test *Test) modify() {
    test.a++
}

func main() {
    test := Test{10}
    fmt.Println(test)
    test.modify()
    fmt.Println(test)

    var a Modifiable

    a = test
}

它报错说:

"Test does not implement Modifiable (modify method has pointer receiver)"

为什么会发生这种情况?

Golang实际上是如何处理方法调用的?

英文:

According this question, golang will generate both type-receiver method and point-receiver method, which means the code below will work correctly and the value will change unexpectedly.

func (test *Test) modify() {
    test.a++
}

func main() {
    test := Test{10}
    fmt.Println(test)
    test.modify()
    fmt.Println(test)
}

I think it's acceptable to me. But when this mixes with interface, thing goes wrong.

type Modifiable interface {
    modify()
}

type Test struct {
    a int
}

func (test *Test) modify() {
    test.a++
}

func main() {
    test := Test{10}
    fmt.Println(test)
    test.modify()
    fmt.Println(test)

    var a Modifiable

    a = test
}

it said:

Test does not implement Modifiable (modify method has pointer receiver)

Why will this happen ?

And how golang actually handle method call ?

答案1

得分: 1

如果你想使用具有指针接收器的方法,这意味着你必须传递地址值。

这是一个例子:

package main

import "fmt"

type Modifiable interface {
	modify()
}

type Test struct {
	a int
}

func (test *Test) modify() {
	test.a++
}

func main() {
	test := Test{10}
	fmt.Println(test)
	test.modify()
	fmt.Println(test)

	var a Modifiable

	a = &test
	a.modify()
	fmt.Println(a)
}

总结一下,当你在方法中创建一个指针接收器时,接口将接受地址值。

英文:

if you wanted to use a method that has pointer receiver. It means you have to pass the address value.

here is the example :

package main

import "fmt"

type Modifiable interface {
	modify()
}

type Test struct {
	a int
}

func (test *Test) modify() {
	test.a++
}

func main() {
	test := Test{10}
	fmt.Println(test)
	test.modify()
	fmt.Println(test)

	var a Modifiable

	a = &test
	a.modify()
	fmt.Println(a)
}

In conclusion an interface will accept the address value whenever you create a pointer receiver in the method.

答案2

得分: 1

当你说:

func (test *Test) modify() {
    test.a++
}

这意味着类型 *Test 实现了接口 Modifiable,也就是 指向 Test 的指针

func (test Test) modify() {
    test.a++
}

意味着类型 Test 实现了接口

结论是:类型和指向该类型的指针是两种不同的类型。

英文:

When you said:

func (test *Test) modify() {
    test.a++
}

It means the interface Modifiable is implemented by the type *Test aka the Pointer to Test

Where as

func (test Test) modify() {
    test.a++
}

means that the interface is implemented by the type Test

Conclusion is: A type and a pointer to that type are 2 different types.

huangapple
  • 本文由 发表于 2017年1月11日 09:27:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/41581309.html
匿名

发表评论

匿名网友

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

确定