Golang中接口实现和调用的代码问题求解
Golang中接口实现和调用的代码问题求解 请先回答以下问题再提交问题,谢谢!
你使用的 Go 版本是什么(go version)?
- go version go1.11 darwin/amd64
这个问题在最新版本中是否仍然存在?
- 未测试
你使用的操作系统和处理器架构是什么(go env)?
- 与此无关
你做了什么?
如果可能,请提供重现错误的步骤。
一个完整的可运行程序更好。
在 play.golang.org 上的链接最佳。
代码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)却得到相同答案,这让我感到困惑。
更多关于Golang中接口实现和调用的代码问题求解的实战教程也可以访问 https://www.itying.com/category-94-b0.html
2 回复
我认为解决您问题的方法是将结构体作为引用传递。
https://play.golang.org/p/Vucg9bflX9f
更多关于Golang中接口实现和调用的代码问题求解的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go语言中,接口实现和调用的行为取决于方法接收器的类型。让我分析这三个代码示例:
代码1和代码2分析
代码1和代码2实际上是相同的(代码1中注释掉了一行),它们都使用值接收器:
func (e esc) GotU() {
e.i = 10
}
输出结果都是9的原因:
- 值接收器操作的是副本,对字段的修改不会影响原始对象
TestFunc(test)传递的是esc类型的值,接口方法操作的是这个值的副本
代码3分析
代码3使用指针接收器:
func (e *esc) GotU() {
e.i = 10
}
编译错误的原因:
*esc类型实现了myintf接口,但esc类型没有TestFunc(test)传递的是esc值类型,不满足接口要求
正确的指针接收器用法
要让代码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) // 输出: 10
}
关键区别总结
// 值接收器 - 操作副本,不影响原对象
func (e esc) GotU() {
e.i = 10 // 修改的是副本
}
// 指针接收器 - 操作原对象
func (e *esc) GotU() {
e.i = 10 // 修改的是原对象
}
接口实现规则:
- 值类型
T的方法集包含所有值接收器声明的方法 - 指针类型
*T的方法集包含所有值接收器和指针接收器声明的方法
这就是为什么代码1和代码2能工作(值类型实现了接口),而代码3需要传递指针才能编译通过。

