2011-01-25 11 views
36

Estoy escribiendo un juego en go. En C++, almacenaría todas mis clases de entidad en una matriz de la clase BaseEntity. Si una entidad necesita moverse en el mundo, sería una PhysEntity que se deriva de una BaseEntity, pero con métodos adicionales. Traté de imitar esto es ir:Casting back to más specialized interface

package main 

type Entity interface { 
    a() string 
} 

type PhysEntity interface { 
    Entity 
    b() string 
} 

type BaseEntity struct { } 
func (e *BaseEntity) a() string { return "Hello " } 

type BasePhysEntity struct { BaseEntity } 
func (e *BasePhysEntity) b() string { return " World!" } 

func main() { 
    physEnt := PhysEntity(new(BasePhysEntity)) 
    entity := Entity(physEnt) 
    print(entity.a()) 
    original := PhysEntity(entity) 
// ERROR on line above: cannot convert physEnt (type PhysEntity) to type Entity: 
    println(original.b()) 
} 

Esto no se compilará, ya que no puede decir que la 'entidad' era un PhysEntity. ¿Cuál es una alternativa adecuada para este método?

Respuesta

59

Utilice un type assertion. Por ejemplo,

original, ok := entity.(PhysEntity) 
if ok { 
    println(original.b()) 
} 
+1

¿Sabes si las aserciones de tipo son caras de usar? ¿Merece la pena seguir el tipo con una variable en BaseEntity? –

+4

las afirmaciones de tipo son baratas. – rog

+0

Cuando intento esto, aparece un error: 'aserción de tipo no válido ... (tipo no de interfaz ... a la izquierda)' – Zac

5

Específicamente, el tipo Go "interfaz" tiene la información en lo que realmente era el objeto, que se hizo pasar por la interfaz, por lo echando es mucho más barato que un ++ dynamic_cast C o el Test- java equivalente y echado