2016-01-31 19 views
8

uczę odchodzenie lang i zastanawiałem się, czy istnieje sposób, aby zrobić coś takiego:Polimorfizm idź lang

type Foo struct { 
    ... 
} 

type Bar struct { 
    Foo 
    ... 
} 

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

W języku obiektowym, taki kod powinien działać bez problemów, ale w podróży rzuca mi błąd, mówiąc, że getFoo() musi zwrócić instancję klasy Foo.

Czy istnieje sposób na polimorfizm podobny do tego, co opisałem w Go?

+1

Myślę, że można tworzyć i zwracać https://gobyexample.com/interfaces interfejsu – dm03514

Odpowiedz

11

Go nie jest typowym językiem OO. Także każdy język ma własny sposób robienia rzeczy. Można użyć interfejsu i kompozycji, aby osiągnąć to, czego pragniesz, jak pokazano poniżej:

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

słyszałem problem z interfejsem jest to, że traci kontrolę kompilacji typu czasu, prawda? – m0meni

+4

Myślę, że mylicie "interfejs" z "interfejsem {}" .. Go nadal będzie wpisywać interfejsy check podczas kompilacji, to po prostu sprawdzi, czy zmienna jest instancją tego interfejsu. Problem z "interfejsem {}" polega na tym, że ponieważ funkcje, które należy dopasować do interfejsu, to pusty zestaw, wszystko pasuje do niego i tracisz kontrolę typu kompilacji. – driusan

+0

przyda się niesamowita odpowiedź! Dzięki – m0meni

3

w Go, polimorfizm jest osiągnięty poprzez wdrożenie interfejsów.

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 
} 

Dlatego nic nie implementuje pustego interfejsu.

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 
}