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

标签 go

Go 似乎并没有强制遵循接口(interface)的结构。为什么下面的代码可以编译?

package main

type 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.go
panic: 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 +0x3f4
main.(*LocalStruct).SomeMethod(0xc0820064e0, 0x47bf30, 0x13, 0x0, 0x0)
        <autogenerated>:3 +0x70
main.main()
        C:/Users/kdeenanauth/Documents/git/go/src/gitlab.com/kdeenanauth/structTest/main.go:16 +0x98
exit status 2

最佳答案

当嵌入类型时(在您的示例中,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)
}

因为 LocalInterface 字段为 nil,您的程序因 nil 指针取消引用而发生困惑。

以下程序“修复”了 panic (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")
}

关于go - 为什么 Go 允许我调用未实现的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36758900/

相关文章:

go - 检查go代码是否已经格式化

go - 如何在 GO 中的 Conn 中编写响应(类型 Response)?

go - 每次计时器结束时运行函数的最有效方法,但有大量计时器(千/百万)

go - 在 fmt.Sprintf 格式字符串中多次引用同一参数

json - Golang 将嵌套的 json 解码为结构

go - 如何检查声明为 map[string]interface{} 的变量实际上是 map[string]string?

go - Golearn模型对自变量(预测变量)和目标(预测变量)是隐式的

json - 解码 JSON 值,可以是字符串或数字

encryption - golang中如何使用rsa key 对进行AES加解密

递归链接对象的算法