2016-01-31 16 views
8

sto imparando andare lang e mi chiedevo se c'è un modo per fare qualcosa di simile:polimorfismo in Go lang

type Foo struct { 
    ... 
} 

type Bar struct { 
    Foo 
    ... 
} 

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

In un linguaggio orientato agli oggetti, tale codice dovrebbe funzionare senza problemi, ma in movimento mi viene un errore, dicendo che getFoo() deve restituire un'istanza di classe Foo.

C'è un modo per fare il polimorfismo simile a quello che ho descritto in Go?

+1

Penso che si potrebbe creare e restituire un https://gobyexample.com/interfaces interfaccia – dm03514

risposta

11

Go non è un tipico linguaggio OO. Inoltre ogni lingua ha il proprio modo di fare le cose. È possibile utilizzare l'interfaccia e la composizione per raggiungere ciò che si desidera, come illustrato di seguito:

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

Ho sentito il problema con l'interfaccia è che perde compilazione tipo di tempo di controllo, giusto? – m0meni

+4

Penso che tu stia confondendo "interfaccia" con "interfaccia {}". Go continuerà a digitare le interfacce di controllo in fase di compilazione, controllerà solo che la variabile sia un'istanza di tale interfaccia. Il problema con "interface {}" è che, dal momento che le funzioni che devono essere abbinate per l'interfaccia è il set vuoto, tutto lo combacia e si perde il controllo del tipo a tempo di compilazione. – driusan

+0

@driusan risposta fantastica! Grazie – m0meni

3

In Vai, il polimorfismo si ottiene da interfacce di attuazione.

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 
} 

Pertanto, qualsiasi cosa implementa un'interfaccia vuota.

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 
}