2014-06-22 13 views
6

Sto scrivendo un codice Swift dove ho una matrice contenente un tipo generico:di Apple Swift: Tipo Generics Casting

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

Più tardi nel mio codice ho bisogno di determinare il tipo memorizzato nella matrice. Ho provato ad usare la tecnica di fusione del tipo descritta nello documentation (sebbene non fosse usato per i generici).

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 
} 

I suddetti risultati istruzione switch il seguente errore su di compilazione:

  1. While emitting IR SIL function @_TFC19Adder_Example___Mac6Matrix9transposeUS_7Element__fGS0_Q__FT_GSqGS0_Q___ for 'transpose' at /code.viperscience/Adder/src/Adder Library/Matrix.swift:45:3 :0: error: unable to execute command: Segmentation fault: 11 :0: error: swift frontend command failed due to signal (use -v to see invocation) Command /Applications/Xcode6-Beta2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift failed with exit code 254

Qualcuno sa come posso lanciare i miei dati generici al suo tipo reale al fine di adottare misure specifiche?

+0

Provare a usare 'as?' Ma penso che nel tuo caso sia un bug del compilatore ... segnalalo! – Jack

+1

Ho provato l'opzionale ma non ha funzionato. Sono d'accordo che probabilmente è un bug del compilatore. Non è il primo che ho visto relativo ai farmaci generici ... – nalyd88

risposta

1

Supponiamo di avere una serie di pulsanti:

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

È possibile utilizzare questi calchi:

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

Se si tenta di utilizzare come in caso di streghe come sotto, non funzionerà. Il compilatore (Swift 1.2 Xcode 6.3b1) dice: "Non è possibile utilizzare pattern di tipo downcast [NSButton]."

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

Chiamarlo una limitazione. Inserisci un radar con il tuo caso d'uso. Il team di Swift è davvero pronto ad ascoltare il feedback. Se si vuole davvero farlo funzionare, è possibile definire il proprio operatore di corrispondenza del modello. In questo caso sarebbe qualcosa di simile:

struct ButtonArray { } 
let isButtonArray = ButtonArray() 

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

Allora questo funziona:

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

Provalo in un parco giochi. Spero che sia d'aiuto!

2

In rapido, as operatore è qualcosa di simile dynamic_cast in C++, che può essere utilizzato per lanciare giù un oggetto.

Opinione avete un oggetto a di tipo A, e si può scrivere let a as B solo quando tipo B è identico al tipo A, o B è una sottoclasse di A.

Nel tuo caso, apparentemente Array<T> non è sempre possibile eseguire il cast per Array<Double> o Array<Float>, quindi il compilatore segnala errori.

una semplice correzione è quello di convertire in AnyObject prima, e poi abbattuti a Array<Double> o 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 
+0

Grazie per l'aiuto, ma ho cercato inutilmente la soluzione, anche se la tua spiegazione è stata utile.Mi rendo conto che Array non può sempre essere lanciato su Array o Array ma non è questo ciò che è l'istruzione switch? Non dovrebbe davvero importare ... Sto pensando che questo sia un errore con il compilatore. Inoltre, usando As? l'operatore genera solo un altro errore. La documentazione di Apple (vedi il mio link sopra) non usa la Come? operatore, ma solo l'operatore As. – nalyd88