2016-04-21 11 views
3

Go scheint die struct-Schnittstelle nicht zu erzwingen. Warum kompiliert der folgende Code? Warum erlaubt Go mir Methoden aufzurufen, die nicht implementiert sind?

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") 
} 

Es scheint, wie sollte dies nicht kompilieren, da SomeMethod nicht implementiert. go build ergibt keine Probleme.

Laufen führt es in dem Laufzeitfehler:

> 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 

Antwort

6

Wenn ein Typ (in Ihrem Beispiel LocalInterface innerhalb LocalStruct eingebettet ist) eingebettet ist, Go ein Feld des eingebetteten Typs erzeugt und fördert seine Methoden des umschließenden Art.

So ist die folgende Erklärung

type LocalStruct struct { 
    LocalInterface 
    myOwnField string 
} 

entspricht

type LocalStruct struct { 
    LocalInterface LocalInterface 
    myOwnField string 
} 

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

Ihr Programm panics mit Null Pointer-Dereference, weil LocalInterface Feld nil ist.

Die folgende Programm „fixe“ die Panik (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

ich vergessen hatte, es ist ein verstecktes Feld und eine Null-Zeiger-Ausnahme ist absolut sinnvoll. Vielen Dank für die Veranschaulichung eines Fixes, bei dem ein anderer Typ eingeführt wurde, um die Oberfläche zu vervollständigen! –

0

Bei mir einem weiteren Untersuchung, dass die Einbettung der ordnungsgemäßen Fehlerbehandlung Behandlung wird vermieden gefunden. Das wäre in meinem Fall bevorzugt werden:

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") 
} 

Ergebnisse in:

.\main.go:13: cannot use LocalStruct literal (type *LocalStruct) as type LocalInterface in assignment: *LocalStruct does not implement LocalInterface (missing SomeMethod method)

Verwandte Themen