2016-01-31 1 views
8

Ich gehe lang lerne, und ich frage mich, ob es einen Weg gibt, etwas zu tun:Polymorphismus in Go lang

type Foo struct { 
    ... 
} 

type Bar struct { 
    Foo 
    ... 
} 

func getFoo() Foo { 
    return Bar{...} 
} 

In einer objektorientierten Sprache, wie Code sollte ohne Probleme funktionieren, aber in go Es wirft einen Fehler auf, der besagt, dass getFoo() eine Instanz der Klasse Foo zurückgeben muss.

Gibt es eine Möglichkeit Polymorphie zu machen, ähnlich wie ich es in Go beschrieben habe?

+1

Ich glaube, Sie könnten eine Schnittstelle https://gobyexample.com/interfaces erstellen und das Rück – dm03514

Antwort

11

Go ist keine typische OO-Sprache. Auch jede Sprache hat ihre eigene Art, Dinge zu tun. Sie können Schnittstelle und Zusammensetzung verwenden, um zu erreichen, was Sie wünschen, wie unten dargestellt:

package main 

import "fmt" 

type Foo interface { 
    printFoo() 
} 

type FooImpl struct { 

} 

type Bar struct { 
    FooImpl 
} 

type Bar2 struct { 
    FooImpl 
} 

func (f FooImpl)printFoo(){ 
    fmt.Println("Print Foo Impl") 
} 

func getFoo() Foo { 
    return Bar{} 
} 

func main() { 
    fmt.Println("Hello, playground") 
    b := getFoo() 
    b.printFoo() 
} 

http://play.golang.org/p/iR8QkD3DnP

+0

ich das Problem mit Schnittstelle gehört habe, ist, dass es verliert Typüberprüfung kompilieren, nicht wahr? – m0meni

+4

Ich denke, Sie verwirren "Schnittstelle" mit "Schnittstelle {}" .. Go wird immer noch Check-Schnittstellen zum Zeitpunkt der Kompilierung eingeben, wird es nur überprüfen, dass die Variable eine Instanz dieser Schnittstelle ist. Das Problem mit "interface {}" besteht darin, dass, da die Funktionen, die für die Schnittstelle abgeglichen werden müssen, die leere Menge ist, alles mit ihr übereinstimmt und Sie die Überprüfung der Kompilierzeitart verlieren. – driusan

+0

@driusan tolle Antwort! Vielen Dank – m0meni

3

In Go, Polymorphismus durch die Implementierung von Schnittstellen erreicht wird.

type Being interface { 
     somemethod() 
} 

type Foo struct {} 

type Bar struct { 
     Foo 
} 

type Baz struct { 
     Foo 
} 

// `Bar` and `Baz` implement `Being` 
func (b *Bar) somemethod() {} 
func (b *Baz) somemethod() {} 

func getAnyFoo(b *Being) Foo { 
    return b.Foo 
} 

Daher implementiert alles eine leere Schnittstelle.

type Foo struct {} 

type Bar struct { 
     Foo 
} 

// Get anything and extract its `Foo` if anything is a Bar 
func getAnyFoo(i interface{}) Foo { 
     // Normally this would need a type switch to check the type 
     mybar := i.(Bar) 
     return mybar.Foo 
}