Apple Swift: generics de casting

J'écris du code Swift où j'ai un tableau contenant un type générique:

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

Plus tard dans mon code, j'ai besoin de déterminer le type stocké dans le tableau. J'ai essayé d'utiliser la technique de casting de type décrite dans la documentation (bien qu'elle ne soit pas utilisée pour les 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 } 

L'instruction switch ci-dessus entraîne l'erreur suivante lors de la compilation:

  1. Lors de l'émission de la fonction IR SIL @ _FCF19Adder_Example ___ Mac6Masortingx9transposeUS_7Element__fGS0_Q__FT_GSqGS0_Q___ pour 'transposer' dans /code.viperscience/Adder/src/Adder Library / Masortingx.swift: 45: 3: 0: erreur: impossible d'exécuter la command: Erreur de segmentation: 11: 0: erreur: La command frontale swift a échoué en raison du signal (utilisez -v pour voir l'invocation) La command /Applications/Xcode6-Beta2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift a échoué avec le code de sortie 254

Quelqu'un sait-il comment je peux convertir mes données generics à leur type réel afin de prendre des mesures spécifiques?

Supposons que vous ayez un tableau de buttons:

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

Vous pouvez utiliser ces moules:

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

Si vous essayez d'utiliser comme dans un commutateur comme ci-dessous, cela ne fonctionnera pas. Le compilateur (Swift 1.2 Xcode 6.3b1) dit: "Le model Downcast de type [NSButton] ne peut pas être utilisé."

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

Appelez cela une limitation. Déposer un radar avec votre cas d'utilisation. L'équipe de Swift semble vraiment à l'écoute des commentaires. Si vous voulez vraiment le faire fonctionner, vous pouvez définir votre propre opérateur de correspondance de model. Dans ce cas, ce serait quelque chose comme ceci:

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

Alors cela fonctionne:

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

Essayez-le dans un terrain de jeu. J'espère que cela aide!

Dans swift, l'opérateur est quelque chose comme dynamic_cast en C ++, qui peut être utilisé pour lancer un object.

Supposons que vous ayez un object de type A et que vous n'écriviez let a as B que lorsque le type B est identique au type A ou que B est une sous-class de A

Dans votre cas, Array<T> ne peut pas toujours être réduit vers Array<Double> ou Array<Float> , donc le compilateur signale des erreurs.

Une solution simple consiste à convertir AnyObject abord en AnyObject , puis à AnyObject vers Array<Double> ou 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