Повернення до більш спеціалізованого інтерфейсу


74

Я пишу гру в go. У 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())
}

Це не буде скомпільовано, оскільки не може сказати, що "сутність" була PhysEntity. Яка підходяща альтернатива цьому методу?

go 

Відповіді:


120

Використовуйте твердження типу . Наприклад,

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

3
Чи знаєте ви, чи є твердження типу дорогими у використанні? Чи варто мені відстежувати тип із змінною в BaseEntity?

6
твердження типу дешеві.
rog

Коли я спробую це, я отримую повідомлення про помилку:invalid type assertion .. (non-interface type .. on left)
Zac

1
@Zac, оскільки "твердження типу" дійсне для "інтерфейсу", ваше значення не "інтерфейс".
khue bui

7

Зокрема, тип "інтерфейсу" Go має інформацію про те, яким насправді був об'єкт, який передавався інтерфейсом, тому кастинг набагато дешевший, ніж C ++ dynamic_cast або еквівалентний java-тест і приклад.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.