Apple Swift: Generation Type

I am writing Swift code where I have an array containing a generic type:

let _data: Array<T> = T[]() 

Later in my code I need to determine the type stored in the array. I tried using the type casting method described in the documentation (although it was not used for generics).

 switch self._data { case let doubleData as Array<Double>: // 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 } 

The above switch statement results in the following compilation error:

  • When emitting the IR function, SIL @ _TFC19Adder_Example ___ Mac6Matrix9transposeUS_7Element__fGS0_Q__FT_GSqGS0_Q___ to "transpose" to /code.viperscience/Adder/src/Adder Library / Matrix.swift: 45: 3: 0 error: error: error: error: error: error: error: : quick interface command failed because of a signal (use -v to make a call) The / Applications / Xcode 6-Beta2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift command failed with exit code 254

Does anyone know how I can use my shared data for my actual type to take specific actions?

+6
source share
2 answers

Suppose you have a set 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 the case of the switch, as shown below, this will not work. The compiler (Swift 1.2 Xcode 6.3b1) says: "You cannot use a Downcast template like [NSButton].

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

What is this limitation? Create a radar with your use case. The Swift team really throws to listen to reviews. If you really want to make it work, you can define your own pattern matching operator. In this case, it will be something like this:

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

Then it works:

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

Try it on the playground. Hope this helps!

+1
source

In the swift statement, the as statement is something like dynamic_cast in C ++, which can be used to down an object.

Say you have an object a type a , and you can write let a as B only when type B is identical to type a , or B is a subclass of a .

In your case, apparently, Array<T> cannot always be ported to Array<Double> or Array<Float> , so the compiler reports errors.

A simple fix is ​​to convert to AnyObject first and then AnyObject down 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 
+2
source

Source: https://habr.com/ru/post/971187/


All Articles