可选择转换为其类型为Swift中的类类型的变量

时间:2016-07-16 14:36:33

标签: swift types casting sprite-kit

我在Google和SO上搜索过类似的问题,找不到任何与此直接相关的问题。在C#中似乎有两个相似(可能是?)的问题,但我不懂语言,所以我没有真正理解这些问题(How to cast object to type described by Type class?Cast a variable to a type represented by another Type variable?)。

我正在尝试在SpriteKit的 GameViewController 中编写通用的场景更改功能。我创建了一个 SceneChangeType 枚举作为参数。尝试将变量强制转换为我期望的泛型类型时出现错误。

为了澄清,我确信有很多理由说明这不是一个好主意。我可以想到处理场景变换的其他方法,比如为每个场景变化编写单独的方法。我只是从技术角度感到好奇,为什么我收到一个我无法理解的错误。

相关代码如下:

GameViewController.swift

func genericSceneChangeWithType(sceneChangeType: SceneChangeType) {
    let expectedType = sceneChangeType.oldSceneType
    guard let oldScene = self.currentScene as? expectedType else { return }
    ...
}

enum SceneChangeType {
    case TitleSceneToGameScene
    var oldSceneType: SKScene.Type {
        switch self {
        case .TitleSceneToGameScene:
            return TitleScene.self
        }
    }
    ...
}

为了澄清, TitleScene SKScene 的自定义子类,自我 .currentScene的类型为 SKScene?

在线,

guard let oldScene = self.currentScene as? expectedType else { return }

我收到了错误,

'expectedType' is not a type

我只是在这里大肆误解事物吗?我以为你可以使用类似的语法从函数中返回泛型类型(例如Swift: how to return class type from function) 问题是因为它是属性吗? 这是不可能的,还是有其他方法来检查类型,如果直到运行时才知道预期的类型?

再次强调,我询问有关更改场景的更好方法,而且我不确定我是否有任何需要绝对的示例。但要理解为什么这不起作用可能会帮助我或其他人更好地理解语言的运作。

谢谢。

2 个答案:

答案 0 :(得分:2)

您有正确的想法,您只是混淆运行时与编译时信息。使用targetSelect.selectmenu(); if($(targetSelect).find('[data-placeholder="true"]').length==0){ phOption = document.createElement('option'); $(phOption).attr('data-placeholder','true'); $(phOption).text("Do a choice"); $(targetSelect).prepend(phOption); } targetSelect.selectmenu('refresh'); 进行投射时,需要在编译时提供类型 。这可以是类似as的显式类型,也可以是通用参数(因为泛型是编译时功能)。但是,您不能传递包含String类型的变量。

你可以做的是检查:

expectedType

但是,由于这不会投射if self.currentScene.dynamicType == expectedType ,因此不允许您调用任何特定于currentScene的方法。如果expectedTypecurrentScene子类,它也可能无法工作,你可能想要它。问题是,当你需要在编译时知道类型 以便调用方法或强制转换时,你在运行时传递类型。

因此,您需要的是Swift语言功能,这些功能看似有用,但在编译时工作,我可以想到两个:

泛型,类似于:

expectedType

重载,类似于:

func genericSceneChange<OldType: SKScene, NewType: SKScene>() {
    ...
}

答案 1 :(得分:1)

这是因为当您将 expectedType 设置为 SceneChangeType 时,它实际上是MetaType的一个实例。 A metatype type refers to the type of any type, including class types, structure types, enumeration types, and protocol types.因此,您无法转发并收到该错误消息。

通过传入Generic类型,您应该能够获得所需的功能。

func genericSceneChangeWithType<T>(sceneChangeType: T) {
  guard let oldScene = self.currentScene as? T else { return }  
}