Apple Swift:Type Casting Generics

我正在写一些Swift代码,其中我有一个包含generics类型的数组:

let _data: Array = T[]() 

稍后在我的代码中,我需要确定存储在数组中的类型。 我尝试使用文档中描述的类型转换技术(尽管它不用于generics)。

 switch self._data { case let doubleData as Array: // Do something with doubleData case let floatData as Array: // Do something with floatData default: return nil // If the data type is unknown return nil } 

上面的switch语句在编译时导致以下错误:

  1. 在/code.viperscience/Adder/src/Adder Library / Matrix.swift:45:3:0:错误:无法执行命令时发出IR SIL函数@ _TFC19Adder_Example ___ Mac6Matrix9transposeUS_7Element__fGS0_Q__FT_GSqGS0_Q___ for’transpose’:分段错误:11:0:错误: swift前端命令因信号失败(使用-v查看调用)命令/Applications/Xcode6-Beta2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift失败,退出代码为254

有人知道如何将我的通用数据转换为实际类型以采取特定的行动吗?

假设您有一组按钮:

 let views: [NSView] = [NSButton(), NSButton(), NSButton()] 

你可以使用这些演员表:

 let viewsAreButtons = views is [NSButton] // returns true let buttonsForSure = views as! [NSButton] // crashes if you are wrong let buttonsMaybe = views as? [NSButton] // optionally set 

如果您尝试使用如下所示的开关盒,它将无法正常工作。 编译器(Swift 1.2 Xcode 6.3b1)说:“不能使用[NSButton]类型的Downcast模式。”

 switch views { case let buttons as [NSButton]: println("Buttons") default: println("something else") } 

称之为限制。 使用您的用例提交雷达。 Swift团队真正接受了反馈。 如果您真的想让它工作,您可以定义自己的模式匹配运算符。 在这种情况下,它将是这样的:

 struct ButtonArray { } let isButtonArray = ButtonArray() func ~=(pattern: ButtonArray, value: [NSView]) -> Bool { return value is [NSButton] } 

然后这工作:

 switch views { case isButtonArray: println("Buttons") // This gets printed. default: println("something else") } 

在游乐场尝试一下。 希望能帮助到你!

在swift中,运算符类似于C ++中的dynamic_cast ,可用于向下转换对象。

假设你有一个类型A的对象a ,只有当类型B与类型A相同或者BA的子类时,才能写let a as B

在您的情况下,显然Array不能总是向下转换为ArrayArray ,因此编译器报告错误。

一个简单的解决方法是首先转换为AnyObject ,然后向下转换为ArrayArray

 let anyData: AnyObject = self._data; switch anyData { case let doubleData as? Array: // use as? operator, instead of as, // to avoid runtime exception // Do something with doubleData case let floatData as? Array: // Do something with floatData default: return nil // If the data type is unknown return nil