为了账号安全,请及时绑定邮箱和手机立即绑定

为什么 Go 允许我调用未实现的方法?

为什么 Go 允许我调用未实现的方法?

Go
慕尼黑8549860 2022-01-04 21:15:13
Go 似乎没有强制遵守接口的结构。为什么下面的代码会编译?package maintype LocalInterface interface {    SomeMethod(string) error    SomeOtherMethod(string) error}type LocalStruct struct {    LocalInterface    myOwnField string}func main() {    var localInterface LocalInterface = &LocalStruct{myOwnField:"test"}    localInterface.SomeMethod("calling some method")}似乎这不应该编译,因为SomeMethod没有实现。go build结果没有问题。运行它会导致运行时错误:> go run main.gopanic: runtime error: invalid memory address or nil pointer dereference[signal 0xc0000005 code=0x0 addr=0x20 pc=0x4013b0]goroutine 1 [running]:panic(0x460760, 0xc08200a090)        C:/Go/src/runtime/panic.go:464 +0x3f4main.(*LocalStruct).SomeMethod(0xc0820064e0, 0x47bf30, 0x13, 0x0, 0x0)        <autogenerated>:3 +0x70main.main()        C:/Users/kdeenanauth/Documents/git/go/src/gitlab.com/kdeenanauth/structTest/main.go:16 +0x98exit status 2
查看完整描述

2 回答

?
森栏

TA贡献1810条经验 获得超5个赞

当一个类型被嵌入(在你的例子中LocalInterface被嵌入在里面LocalStruct)时,Go 会创建一个嵌入类型的字段并将其方法提升为封闭类型。


所以下面的声明


type LocalStruct struct {

    LocalInterface

    myOwnField string

}

相当于


type LocalStruct struct {

    LocalInterface LocalInterface

    myOwnField string

}


func (ls *LocalStruct) SomeMethod(s string) error {

    return ls.LocalInterface.SomeMethod(s)

}

您的程序因 nil 指针取消引用而恐慌,因为LocalInterfacefield 是nil.


以下程序“修复”了恐慌(http://play.golang.org/p/Oc3Mfn6LaL):


package main


type LocalInterface interface {

    SomeMethod(string) error

}


type LocalStruct struct {

     LocalInterface

    myOwnField string

}


type A int


func (a A) SomeMethod(s string) error {

    println(s)

    return nil

}


func main() {

    var localInterface LocalInterface = &LocalStruct{

        LocalInterface: A(10),

        myOwnField:     "test",

    }


    localInterface.SomeMethod("calling some method")

}


查看完整回答
反对 回复 2022-01-04
?
万千封印

TA贡献1891条经验 获得超3个赞

经过进一步调查,我发现避免嵌入得到了适当的错误处理处理。在我的情况下,这将是首选:


package main


type LocalInterface interface {

    SomeMethod(string) error

    SomeOtherMethod(string) error

}


type LocalStruct struct {

    myOwnField string

}


func main() {

    var localInterface LocalInterface = &LocalStruct{myOwnField:"test"}


    localInterface.SomeMethod("calling some method")

}

结果是:


.\main.go:13:不能在赋值中使用 LocalStruct 文字(类型 *LocalStruct)作为 LocalInterface 类型:*LocalStruct 没有实现 LocalInterface(缺少 SomeMethod 方法)


查看完整回答
反对 回复 2022-01-04
  • 2 回答
  • 0 关注
  • 225 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信