首页 文章

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

提问于
浏览
4

我找不到任何直接相关的东西 . 在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
        }
    }
    ...
}

为了澄清, TitleSceneSKScene 的自定义子类,self.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

    你有正确的想法,你只是混淆运行时与编译时信息 . 使用 as 进行转换时,需要在编译时提供类型 . 这可以是 String 之类的显式类型,也可以是通用参数(因为泛型是编译时功能) . 但是,您不能传递包含类似 expectedType 类型的变量 .

    你可以做的是检查:

    if self.currentScene.dynamicType == expectedType
    

    但是,由于这不会转换 currentScene ,因此它不允许您调用特定于 expectedType 的任何方法 . 如果 currentSceneexpectedType 的子类,并且您可能想要它,它也将无效 . 问题是你在运行时传递类型,当你需要在编译时知道类型以调用方法或强制转换 .

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

    Generics ,类似于:

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

    Overloading ,类似于:

    func changeTo(scene: OneType) {
        //do something
    }
    
    func changeTo(scene: OtherType) {
        //do something else
    }
    
  • 2

    那是因为当你将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 }  
    }
    

相关问题