投射回更专业的界面


74

我正在写游戏。在C ++中,我会将所有实体类存储在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())
}

这将无法编译,因为它无法告知“实体”是PhysEntity。有什么方法可以替代此方法?

go 

Answers:


120

使用类型断言。例如,

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

3
您知道类型断言使用起来是否昂贵?是否值得在BaseEntity中使用变量跟踪类型?

6
类型断言很便宜。
罗格

当我尝试此操作时,出现错误:invalid type assertion .. (non-interface type .. on left)
Zac

1
@Zac,因为“类型断言”在“接口”上有效,因此您的值不是“接口”。
坤布

7

具体来说,Go的“接口”类型具有通过接口传递的对象的真实信息,因此强制转换比C ++ dynamic_cast或等效的Java测试和发布便宜得多。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.