2014-06-22 9 views
6

Piszę jakiś kod SWIFT gdzie mam tablicę zawierającą typ rodzajowy:Jabłko Swift: Rodzaj Castingi Generics

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

Później w moim kodu muszę ustalić rodzaj przechowywanej w tablicy. Próbowałem używać techniki odlewania typu opisanej w documentation (chociaż nie była używana w przypadku generycznych).

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 
} 

Powyższe wyniki rachunku przełącznik w następującym błędem upon kompilacji:

  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

ktoś wie jak mogę rzucić moje dane ogólne do jego rzeczywistego typu w celu podjęcia konkretnych działań?

+0

Spróbuj użyć 'jak?' Ale myślę, że w twoim przypadku jest to błąd kompilatora ... zgłoś to! – Jack

+1

Próbowałem opcji, ale nie działało. Zgadzam się prawdopodobnie z błędem kompilatora. To nie pierwsza z nich, którą widziałem w odniesieniu do generycznych ... – nalyd88

Odpowiedz

1

Załóżmy, że mamy szereg przycisków:

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

Można użyć tych odlewane:

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

Jeśli spróbujesz użyć jak w Przykład czarownic jak poniżej, to nie zadziała. Kompilator (Swift 1.2 Xcode 6.3b1) mówi: "Downcast typu [NSButton] nie może być użyty."

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

Nazwać to ograniczeniem. Złóż radar za pomocą swojego przypadku użycia. Zespół Swift naprawdę szykuje się do wysłuchania opinii. Jeśli naprawdę chcesz, aby to działało, możesz zdefiniować własny operator dopasowywania wzorców. W tym przypadku będzie to coś takiego:

struct ButtonArray { } 
let isButtonArray = ButtonArray() 

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

Wtedy to działa:

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

Spróbuj to na placu zabaw. Mam nadzieję, że to pomoże!

2

w Swift, as operator jest coś takiego jak dynamic_cast w C++, które mogą być wykorzystane do dół cast obiektem.

Powiedzmy, że masz obiekt a typu A i można napisać let a as B tylko wtedy, gdy typ B jest identyczny typ A lub B to podklasa A.

W twoim przypadku najprawdopodobniej Array<T> nie zawsze może być rzucany do Array<Double> lub Array<Float>, więc kompilator zgłasza błędy.

Prostym rozwiązaniem jest konwersja do AnyObject, a potem przybity do Array<Double> lub 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

Dziękuję za pomoc, ale wypróbowałem twoje rozwiązanie bezskutecznie - chociaż twoje wyjaśnienie było pomocne.Zdaję sobie sprawę, że Array nie zawsze może być rzutowany w dół na Array lub Array , ale czy nie jest to tym, do czego służy instrukcja switch? To naprawdę nie powinno mieć znaczenia ... Myślę, że to jest błąd z kompilatorem. Ponadto, używając As? Operator generuje tylko inny błąd. Dokumentacja Apple (zobacz mój link powyżej) nie używa As? operator, ale raczej jako operator As. – nalyd88