2015-09-18 15 views
10

E 'possibile verificare se una variabile è un optional, e che tipo è a capo?Controlla se la variabile è un Opzionale e che tipo si incastra

E 'possibile controllare se una variabile è un particolare optional:

let someString: String? = "oneString" 
var anyThing: Any = someString 

anyThing.dynamicType // Swift.Optional<Swift.String> 
anyThing.dynamicType is Optional<String>.Type // true 
anyThing.dynamicType is Optional<UIView>.Type // false 

Ma è possibile controllare agains qualsiasi tipo di optional? Qualcosa di simile:

anyThing.dynamicType is Optional.Type // fails since T cant be inferred 
// or 
anyThing.dynamicType is Optional<Any>.Type // false 

E una volta che sapendo di avere un optional, recuperare il tipo si è avvolgente:

// hypothetical code 
anyThing.optionalType // returns String.Type 
+0

In ogni caso, non si dovrebbe mettere '' Optional' in Any'. vedere: [Come scartare un valore facoltativo da Qualsiasi tipo?] (http://stackoverflow.com/q/27989094/3804019) – rintaro

+0

Potrebbe essere un caso valido, potresti avere una funzione che accetta 'Qualsiasi' e che si comporta diversamente se riceve un 'Optional'. – LopSae

risposta

5

Con Swift2.0:

let someString: String? = "oneString" 
var anyThing: Any = someString 

// is `Optional` 
Mirror(reflecting: anyThing).displayStyle == .Optional // -> true 

Ma l'estrazione di tipo avvolto non è così facile.

Si potrebbe:

anyThing.dynamicType // -> Optional<String>.Type (as Any.Type) 
Mirror(reflecting: anyThing).subjectType // -> Optional<String>.Type (as Any.Type) 

Ma io non so come estrarre String.Type da Optional<String>.Type avvolto con Any.Type

+0

Finora sembra che sia attualmente impossibile estrarre 'String.Type' da' Optional .self'. Tuttavia è possibile estendere l'enume 'Optional' per fornire un metodo che restituisca il tipo avvolto e utilizzare qualsiasi istanza per accedervi. – LopSae

+0

Come [questo] (http://stackoverflow.com/a/28964069/3804019)? Quando disponi di 'Opzionale .self' come' Opzionale .Tipo', puoi farlo. Ma penso che sia impossibile per "Any.Type". – rintaro

+0

Mi hai appena insegnato come farlo: se hai 'permetti anyType: Any.Type = Array .self', quindi basta lanciarlo indietro:' (anyType as! Array .Type) .Element.self' restituirà 'String.Type' :) – LopSae

6

Dal a protocol can be created as means of a typeless Optional lo stesso protocollo può essere utilizzato per fornire l'accesso al tipo di optional. Esempio è a Swift 2, anche se dovrebbe funzionare in modo simile nelle versioni precedenti:

protocol OptionalProtocol { 
    func wrappedType() -> Any.Type 
} 

extension Optional : OptionalProtocol { 
    func wrappedType() -> Any.Type { 
     return Wrapped.self 
    } 
} 

let maybeInt: Any = Optional<Int>.Some(12) 
let maybeString: Any = Optional<String>.Some("maybe") 

if let optional = maybeInt as? OptionalProtocol { 
    print(optional.wrappedType()) // Int 
    optional.wrappedType() is Int.Type // true 
} 

if let optional = maybeString as? OptionalProtocol { 
    print(optional.wrappedType()) // String 
    optional.wrappedType() is String.Type // true 
} 

Il protocollo può essere utilizzato anche per check and unwrap the contained optional value

+0

Grazie fratello! mi hai salvato la vita! – Sanf0rd

Problemi correlati