Возвращение к более специализированному интерфейсу

Я пишу игру в ходу. В С++ я бы сохранил все мои классы сущностей в массиве класса BaseEntity. Если сущность, необходимая для перемещения в мире, это будет PhysEntity, которая получена из BaseEntity, но с добавленными методами. Я попытался подражать, это идет:

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

Это не будет компилироваться, поскольку он не может сказать, что "entity" был PhysEntity. Что является подходящей альтернативой этому методу?

Ответ 1

Используйте тип утверждения. Например,

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

Ответ 2

В частности, тип интерфейса "Go" имеет информацию о том, что на самом деле был объект, который был передан интерфейсом, поэтому его отличать гораздо дешевле, чем С++ dynamic_cast или эквивалентный Java-тест и литье.