首页 > 解决方案 > 对这些接口实现和调用的代码感到困惑?

问题描述

围棋版本

代码 1:

package main

import "fmt"

type myintf interface {
    GotU()
}

type esc struct {
     i int
}

//func GotU(t esc);
func (e esc)GotU() {
    e.i = 10
}

func TestFunc(it myintf) string {
    it.GotU()
    return  "kk"
}

func main() {

    var test esc
    test.i = 9

    TestFunc(test)

    fmt.Println(test.i)

}

代码 2:

package main

import "fmt"

type myintf interface {
    GotU()
}

type esc struct {
     i int
}

func (e esc)GotU() {
    e.i = 10
}

func TestFunc(it myintf) string {
    it.GotU()
    return  "kk"
}

func main() {

    var test esc
    test.i = 9

    TestFunc(&test)

    fmt.Println(test.i)

}

代码 3:

package main

import "fmt"

type myintf interface {
    GotU()
}

type esc struct {
     i int
}

func (e *esc)GotU() {
    e.i = 10
}

func TestFunc(it myintf) string {
    it.GotU()
    return  "kk"
}

func main() {

    var test esc
    test.i = 9

    TestFunc(test)

    fmt.Println(test.i)

}

输出:


既然只是func (e esc)GotU()实现了,为什么两段代码都应该工作并提供相同的结果?将结构指针传递给该函数(TestFunc)以获得相同的答案对我来说有点令人困惑。

标签: gointerface

解决方案


最后一个代码片段实现了一个指针类型的方法接收器。如果要修改receiver的值,这将考虑这种情况。

func (e *esc) GotU() {
    e.i = 10
}

在上述情况下,由于您在实现接口的方法上传递指针类型接收器。

type myintf interface {
    GotU()
}

所以你需要传递 struct in 的地址TestFunc。这就是您收到类型不匹配错误的原因,因为您正在传递esc类型变量,而您的方法需要*esc.

func main() {

    var test esc
    test.i = 9
    TestFunc(&test)
    fmt.Println(test.i)

}

Go 操场上的工作示例

在 Golang 中有两种方法可以传递方法接收器。

func (s *MyStruct) pointerMethod() { } // method on pointer
func (s MyStruct)  valueMethod()   { } // method on value

对于不习惯指针的程序员来说,这两个例子之间的区别可能会让人感到困惑,但情况其实很简单。当在一个类型上定义一个方法时,接收者(在上面的例子中)表现得就像它是方法的一个参数一样。将接收者定义为值还是指针是同一个问题,那么,函数参数应该是值还是指针。有几个考虑

首先,也是最重要的,该方法是否需要修改接收器?如果是这样,接收者必须是一个指针。(切片和映射充当引用,因此它们的故事有点微妙,但例如要在方法中更改切片的长度,接收者仍然必须是指针。)在上面的示例中,如果 pointerMethod 修改了s,调用者将看到这些更改,但 valueMethod 是使用调用者参数的副本调用的(这是传递值的定义),因此调用者将看不到它所做的更改。


推荐阅读