2015-09-18 13 views
10

Có thể kiểm tra xem biến có phải là tùy chọn hay không và loại đó là gì?Kiểm tra xem biến có phải là Tùy chọn hay không và loại nào kết thúc tốt đẹp

Có thể kiểm tra xem một biến là không bắt buộc một cụ thể:

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 

Nhưng là nó có thể để kiểm tra agains bất kỳ loại hình bắt buộc? Một cái gì đó như:

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

Và một khi biết bạn có một tùy chọn, lấy loại nó được gói:

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

Dù sao, bạn không nên đặt 'Optional' vào' Any'. xem: [Làm thế nào để mở một giá trị tùy chọn từ bất kỳ loại nào?] (http://stackoverflow.com/q/27989094/3804019) – rintaro

+0

Nó có thể là một trường hợp hợp lệ, bạn có thể có một hàm chấp nhận 'Bất kỳ' và hành vi đó khác nếu nó nhận được 'Tùy chọn'. – LopSae

Trả lời

5

Với Swift2.0:

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

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

Nhưng chiết xuất loại bọc không phải là quá dễ.

Bạn có thể:

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

Nhưng tôi không biết làm thế nào để trích xuất String.Type từ Optional<String>.Type được bao bọc bởi Any.Type

+0

Cho đến nay, dường như nó không thể trích xuất 'String.Type' ra khỏi' Tùy chọn .self'. Tuy nhiên, có thể mở rộng enum 'Optional' để cung cấp một phương thức trả về kiểu gói và sử dụng bất kỳ cá thể nào để truy cập nó. – LopSae

+0

Giống như [this] (http://stackoverflow.com/a/28964069/3804019)? Khi bạn có 'Tùy chọn . Tự' là 'Tùy chọn . Loại', bạn có thể. Nhưng tôi nghĩ rằng nó không thể cho 'Any.Type'. – rintaro

+0

Bạn chỉ cần dạy tôi làm thế nào để làm điều đó: nếu bạn có 'let anyType: Any.Type = Array .self', sau đó chỉ cần đưa nó trở lại:' (anyType as! Array .Type) .Element.self' sẽ trở lại 'String.Type' :) – LopSae

6

Kể từ a protocol can be created as means of a typeless Optional giao thức tương tự có thể được sử dụng để cung cấp truy cập vào các loại tùy chọn. Ví dụ là trong Swift 2, mặc dù nó cũng làm việc tương tự như trong các phiên bản trước:

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 
} 

Giao thức thậm chí có thể được sử dụng để check and unwrap the contained optional value

+0

Cảm ơn bro! bạn đã cứu cuộc đời tôi! – Sanf0rd

Các vấn đề liên quan