doujiao7679 2018-10-11 14:17
浏览 65
已采纳

对于这些接口实现和调用的代码感到困惑吗?

Version of Go

  • go version go1.11 darwin/amd64

Code 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)

}

Code 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)

}

Code 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)

}

The outputs:

  • code 1 output: 9
  • code 2 output: 9
  • code 3 cannot be compiled due to a type mismatch

Since only func (e esc)GotU() implemented, why should both pieces of code work and deliver the same result? It's kind of confusing for me to pass a pointer of struct to that function (TestFunc) to get the same answer.

  • 写回答

2条回答 默认 最新

  • douxihui8270 2018-10-11 14:30
    关注

    The last code snippet has implemented a method receiver of pointer type. This will consider the situation if you want to modify the value of receiver.

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

    In above case Since you are passing pointer type receiver on a method which is implementing the interface.

    type myintf interface {
        GotU()
    }
    

    So you need to pass address of struct in TestFunc. This is the reason you are getting type mismatch error, because you are passing variable of esc type while your method requires variable of *esc.

    func main() {
    
        var test esc
        test.i = 9
        TestFunc(&test)
        fmt.Println(test.i)
    
    }
    

    Working example on Go playground

    In Golang there are two ways to pass a method receiver.

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

    For programmers unaccustomed to pointers, the distinction between these two examples can be confusing, but the situation is actually very simple. When defining a method on a type, the receiver (s in the above examples) behaves exactly as if it were an argument to the method. Whether to define the receiver as a value or as a pointer is the same question, then, as whether a function argument should be a value or a pointer. There are several considerations

    First, and most important, does the method need to modify the receiver? If it does, the receiver must be a pointer. (Slices and maps act as references, so their story is a little more subtle, but for instance to change the length of a slice in a method the receiver must still be a pointer.) In the examples above, if pointerMethod modifies the fields of s, the caller will see those changes, but valueMethod is called with a copy of the caller's argument (that's the definition of passing a value), so changes it makes will be invisible to the caller.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥100 需要跳转番茄畅听app的adb命令
  • ¥50 寻找一位有逆向游戏盾sdk 应用程序经验的技术
  • ¥15 请问有用MZmine处理 “Waters SYNAPT G2-Si QTOF质谱仪在MSE模式下采集的非靶向数据” 的分析教程吗
  • ¥50 opencv4nodejs 如何安装
  • ¥15 adb push异常 adb: error: 1409-byte write failed: Invalid argument
  • ¥15 nginx反向代理获取ip,java获取真实ip
  • ¥15 eda:门禁系统设计
  • ¥50 如何使用js去调用vscode-js-debugger的方法去调试网页
  • ¥15 376.1电表主站通信协议下发指令全被否认问题
  • ¥15 物体双站RCS和其组成阵列后的双站RCS关系验证