2016-04-21 53 views
3

Go似乎没有强制结构坚持接口。为什么下面的代码编译? 为什么Go允许我调用未实现的方法?

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 

回答

6

当一个类型被嵌入(在你的榜样LocalInterface嵌入内LocalStruct),围棋创建嵌入类型的字段,并促进它的方法封闭类型。

所以下面的声明

type LocalStruct struct { 
    LocalInterface 
    myOwnField string 
} 

因为LocalInterfacenil相当于

type LocalStruct struct { 
    LocalInterface LocalInterface 
    myOwnField string 
} 

func (ls *LocalStruct) SomeMethod(s string) error { 
    return ls.LocalInterface.SomeMethod(s) 
} 

你的程序恐慌与零指针引用。

下面的程序“修复”恐慌(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") 
} 
+0

我已经忘记了这是一个隐藏字段和零指针异常非常有意义。感谢您为说明修复引入了另一种类型的内容来完成界面! –

0

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

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: cannot use LocalStruct literal (type *LocalStruct) as type LocalInterface in assignment: *LocalStruct does not implement LocalInterface (missing SomeMethod method)

相关问题