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

报告相同问题?

悬赏问题

  • ¥15 stm32代码移植没反应
  • ¥15 matlab基于pde算法图像修复,为什么只能对示例图像有效
  • ¥100 连续两帧图像高速减法
  • ¥15 组策略中的计算机配置策略无法下发
  • ¥15 如何绘制动力学系统的相图
  • ¥15 对接wps接口实现获取元数据
  • ¥20 给自己本科IT专业毕业的妹m找个实习工作
  • ¥15 用友U8:向一个无法连接的网络尝试了一个套接字操作,如何解决?
  • ¥30 我的代码按理说完成了模型的搭建、训练、验证测试等工作(标签-网络|关键词-变化检测)
  • ¥50 mac mini外接显示器 画质字体模糊