Возвращение к более специализированному интерфейсу - PullRequest
64 голосов
/ 26 января 2011

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

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.Что является подходящей альтернативой этому методу?

Ответы [ 2 ]

99 голосов
/ 26 января 2011

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

original, ok := entity.(PhysEntity)
if ok {
    println(original.b())
}
7 голосов
/ 27 марта 2015

В частности, тип Go "interface" содержит информацию о том, что на самом деле был объект, который был передан интерфейсом, поэтому приведение к нему намного дешевле, чем C ++ dynamic_cast или эквивалентный java test-and-cast.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...