I\'m writing some Swift code where I have an array containing a generic type:
let _data: Array = T[]()
Later in my code I need to
In swift, as
operator is something like dynamic_cast
in C++, which can be used to down cast an object.
Say you have an object a
of type A
, and you can write let a as B
only when type B
is identical to type A
, or B
is a sub-class of A
.
In your case, apparently Array<T>
cannot always be down cast to Array<Double>
or Array<Float>
, so compiler reports errors.
A simple fix is to convert to AnyObject
first, and then downcast to Array<Double>
or Array<Float>
:
let anyData: AnyObject = self._data;
switch anyData {
case let doubleData as? Array<Double>: // use as? operator, instead of as,
// to avoid runtime exception
// Do something with doubleData
case let floatData as? Array<Float>:
// Do something with floatData
default:
return nil // If the data type is unknown return nil
Suppose you have an array of buttons:
let views: [NSView] = [NSButton(), NSButton(), NSButton()]
You can use these casts:
let viewsAreButtons = views is [NSButton] // returns true
let buttonsForSure = views as! [NSButton] // crashes if you are wrong
let buttonsMaybe = views as? [NSButton] // optionally set
If you try to use as in a switch case like below, it will not work. The compiler (Swift 1.2 Xcode 6.3b1) says: "Downcast pattern of type [NSButton] cannot be used."
switch views {
case let buttons as [NSButton]:
println("Buttons")
default:
println("something else")
}
Call it a limitation. File a radar with your use case. The Swift team really seams to be listening for feedback. If you really want to get it to work, you can define your own pattern matching operator. In this case it would be something like this:
struct ButtonArray { }
let isButtonArray = ButtonArray()
func ~=(pattern: ButtonArray, value: [NSView]) -> Bool {
return value is [NSButton]
}
Then this works:
switch views {
case isButtonArray:
println("Buttons") // This gets printed.
default:
println("something else")
}
Try it in a Playground. Hope it helps!