Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
具有自类型要求的协议的Swift类型擦除_Swift_Generics_Protocols_Type Erasure - Fatal编程技术网

具有自类型要求的协议的Swift类型擦除

具有自类型要求的协议的Swift类型擦除,swift,generics,protocols,type-erasure,Swift,Generics,Protocols,Type Erasure,我试图设计一个简单的游戏引擎,以达到娱乐和教育的目的。我有一个游戏协议来代表我的游戏,还有一个实体协议来代表一个实体(比如玩家或对手)。最后,我有一个EntityComponent协议,它的实现会更新实体。在Swift中看起来是这样的: 协议游戏{ 变量实体:[实体]{get} } 协议实体{ 变量组件:[EntityComponent]{get} } 协议实体组件{ func更新(u实体:实体,延迟时间秒:时间间隔) } 我希望我的实体组件使用它们更新的实体进行通用化。在Swift中,我可以

我试图设计一个简单的游戏引擎,以达到娱乐和教育的目的。我有一个
游戏
协议来代表我的游戏,还有一个
实体
协议来代表一个实体(比如玩家或对手)。最后,我有一个
EntityComponent
协议,它的实现会更新
实体
。在Swift中看起来是这样的:

协议游戏{
变量实体:[实体]{get}
}
协议实体{
变量组件:[EntityComponent]{get}
}
协议实体组件{
func更新(u实体:实体,延迟时间秒:时间间隔)
}
我希望我的实体组件使用它们更新的实体进行通用化。在Swift中,我可以使用
associatedtype

协议实体组件{
associatedtype EntityType:实体
func更新(u实体:EntityType,deltaTime秒数:时间间隔)
}
但是,这将导致
实体
协议的编译错误:

协议实体{
变量组件:[EntityComponent]{get}//错误!
}
协议“EntityComponent”只能用作泛型约束,因为它具有自身或关联的类型要求

通过为
EntityComponent
协议定义类型擦除,并更新
Entity
如下所示,可以解决此问题:

协议实体{
变量组件:[AnyEntityComponent]{get}
}
最终类AnyEntityComponent:EntityComponent{
init(u-component:T),其中T.EntityType==EntityType{
self.update=component.update
}
func更新(u实体:EntityType,deltaTime秒数:时间间隔){
更新(实体,秒)
}
私有let更新:(EntityType,TimeInterval)->Void
}
不幸的是,
实体
协议中的更改产生了另一个问题。这次在
游戏
协议中:

协议游戏{
变量实体:[Entity]{get}//错误!
}
协议“实体”只能用作一般约束,因为它具有自身或关联的类型要求

我不知道如何解决这个问题,因为我无法通过定义类型擦除来解决(比如
EntityComponent


我将感谢任何提示和想法

它可能有助于删除相关的类型要求并改用泛型:

protocol EntityComponent {
    func update<T: Entity>(_ entity: T, deltaTime seconds: TimeInterval)
}
协议实体组件{
函数更新(u实体:T,延迟时间秒:时间间隔)
}

删除相关的类型要求并改用泛型可能会有所帮助:

protocol EntityComponent {
    func update<T: Entity>(_ entity: T, deltaTime seconds: TimeInterval)
}
协议实体组件{
函数更新(u实体:T,延迟时间秒:时间间隔)
}

这是一个很好的提示,谢谢!但是,我希望使用单个
EntityComponent
实现来更新单个
Entity
实现,例如
class PlayerEntity
class PlayerEntityComponent
。啊,这很有意义。我最近也有同样的要求,但我想不出一个优雅的方式来满足。请查看:。它对我不起作用,因为我使用的是结构而不是类,但我认为它会帮助你。非常感谢,我会检查它。这是一个很好的提示,谢谢!但是,我希望使用单个
EntityComponent
实现来更新单个
Entity
实现,例如
class PlayerEntity
class PlayerEntityComponent
。啊,这很有意义。我最近也有同样的要求,但我想不出一个优雅的方式来满足。请查看:。它对我不起作用,因为我使用的是结构而不是类,但我认为它会对你有所帮助。非常感谢,我会查看它