问题描述
我对某些GKState具有以下实现
import GameplayKit.GKState
class Running: GKState {
let validNextStates: [GKState.Type] = [Paused.self,Over.self]
override func isValidNextState(_ stateClass: AnyClass) -> Bool {
return self.validNextStates.contains(where: { stateClass is $0 })
}
}
class Paused: GKState {}
class Over: GKState {}
有人暗示我为什么在Expected type after 'is'
得到$0
吗? validNextStates
被定义为GKState类型的数组,那么为什么其中一个元素未被识别为类型?
编辑:
Xcode:版本12.1(12A7403)
解决方法
问题是stateClass
的类型。 stateClass
的类型为AnyClass
,这只是AnyObject.Type
的类型别名,因此stateClass
是元类型,而不是普通类型,因此is
不能在其上使用运算符。
但是,要比较元类型,可以使用相等运算符。
class Running: GKState {
let validNextStates: [GKState.Type] = [Paused.self,Over.self]
override func isValidNextState(_ stateClass: AnyClass) -> Bool {
return self.validNextStates.contains(where: { $0 == stateClass })
}
}
class Paused: GKState {}
class Over: GKState {}
class Invalid: GKState {}
Running().isValidNextState(Paused.self) // true
Running().isValidNextState(Invalid.self) // false
,
is
不能用于变量。
如果GameplayKit不是用Objective-C编写的,那可能是一个有效的选择。不幸的是,由于isValidNextState
的信息不足,因此无法将其转发到AnyClass
,因此请使用Dávid所示的==
。
func validateNextState<State: GKState>(_: State.Type) throws {
guard ( validNextStates.contains { $0 is State.Type } )
else { throw GKState.Error.invalid }
}
extension GKState {
enum Error: Swift.Error {
case invalid
}
}