go - 对这些接口实现和调用的代码感到困惑?
问题描述
围棋版本
- go 版本 go1.11 darwin/amd64
代码 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)
}
输出:
- 代码 1 输出:9
- 代码 2 输出:9
- 由于类型不匹配,无法编译代码 3
既然只是func (e esc)GotU()
实现了,为什么两段代码都应该工作并提供相同的结果?将结构指针传递给该函数(TestFunc)以获得相同的答案对我来说有点令人困惑。
解决方案
最后一个代码片段实现了一个指针类型的方法接收器。如果要修改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 是使用调用者参数的副本调用的(这是传递值的定义),因此调用者将看不到它所做的更改。
推荐阅读
- react-native - 在抽屉导航上提高警报确认
- excel - 根据值选择VBA中的范围子集
- python - 为什么在条件周围加上括号会有所不同?
- ios - 从 tableView 中删除单元格并从 Firestore iOS 中删除数据
- go - Protobuf 错误 - 找到包 main (main.go) 和 __ (person.pb.go)
- node.js - Docker:发生错误:ffmpeg exited with code 127
- mysql - 您可以为 SQL 子集问题创建输出吗
- amazon-web-services - glue_context.create_dynamic_frame.from_catalog 返回空或空数据
- c# - Windows 窗体中 C1TrueDBGrid 网格中的不可见/隐藏滚动条?
- java - 当我按包运行 mvn 测试时,JUnit 测试通过,但是当我一起运行所有包时,一些测试失败