2015-03-15 16 views
5

Hãy nói rằng tôi có một đoạn mã như thế này:Có thể truyền Bất kỳ tùy chọn nào không?

let x: Int? = 10 
let y: Any = x 

Bây giờ tôi muốn đúc y để int ?:

let z = y as Int? // Error: Cannot downcast from 'Any' to a more optional type 'Int?' 

Đây có phải là chỉ là không thể hoặc là có cách khác?

Trả lời

7

Đối Swift 2.0, bạn có thể sử dụng như sau:

let x: Int? = 10 
let y: Any = x 
let z = Mirror(reflecting: y).descendant("Some") as? Int 

Hoặc như một chức năng:

func castToOptional<T>(x: Any) -> T? { 
    return Mirror(reflecting: x).descendant("Some") as? T 
} 
let x: Int? = 10 
let y: Any = x 
let z: Int? = castToOptional(y) 

Hoặc bạn có thể làm điều này nếu bạn không thích Reflection:

func castToOptional<T>(x: Any) -> T { 
    return x as! T 
} 
let x: Int? = 10 
let y: Any = x 
let z: Int? = castToOptional(y) 
+0

Tôi nghĩ rằng phương pháp này thất bại trong việc đúc 'Any' đến một tùy chọn gõ vào Swift 3/xcode 8. – SimplGy

+0

Ah hah! chữ thường "s" trong 'some'. Ghi chú phát hành đọc hữu ích đôi khi! Đối với nhanh 3, sử dụng 'let z = Mirror (phản ánh: y) .descendant (" some ") là? Int ' – SimplGy

+0

Cách tiếp cận' Mirror (phản xạ: x) .descendant (...) 'không hoạt động trong Swift 3 (' Mirror (phản ánh: x) .children.count' là '0'), nhưng' return x as ! T'! Đối với một số lý do kỳ lạ, cố gắng làm '(myAnyVar như! SCNRenderingAPI?)' Cho tôi một lỗi biên dịch thời gian 'lỗi: không thể downcast từ 'Bất kỳ' sang một loại tùy chọn hơn 'SCNRenderingAPI?'', Nhưng làm cùng một diễn viên bên trong một chức năng như bạn có nó hoạt động tuyệt vời. Chúc mừng! | Chỉnh sửa được đề xuất: _ “Hoặc bạn có thể làm điều này nếu bạn không thích Phản ánh:” _ → _ “Hoặc bạn có thể thực hiện việc này trong Swift 3 hoặc nếu bạn không thích Phản ánh:” _ –

0

Bạn có thể làm điều này để có được một tùy chọn trên Bất kỳ

func unwrap(any:Any) -> Any? { 
    let mi:MirrorType = reflect(any) 
    if mi.disposition != .Optional { 
     return any 
    } 
    if mi.count == 0 { return nil } // Optional.None 
    let (name,some) = mi[0] 
    return some.value 
} 

Vì vậy, trong trường hợp của bạn,

let z = unwrap(y) as? Int

tham khảo: How to unwrap an optional value from Any type?

+0

nhưng đúc không possible..it lợi nhuận bằng không –

0
func castAsOptionalInt(value: Any)->Int? { 
    let mirror = Mirror(reflecting:value) 
    if mirror.subjectType == Optional<Int>.self { 
     let ret = mirror.children.first?.1 
     return ret as? Int 
    } else { 
     return nil 
    } 
} 

let x: Int? = 10 
let y: Any = x 
let z = castAsOptionalInt(y) // 10 
let a: Double? = 10 
let b: Any = a 
let c = castAsOptionalInt(b) // nil 
0

thế nào về giải pháp này, tôi đã thực hiện một phiên bản generic của trước câu trả lời.

fileprivate func unwrap<T>(value: Any) 
    -> (unwraped:T?, isOriginalType:Bool) { 

    let mirror = Mirror(reflecting: value) 
    let isOrgType = mirror.subjectType == Optional<T>.self 
    if mirror.displayStyle != .optional { 
    return (value as? T, isOrgType) 
    } 
    guard let firstChild = mirror.children.first else { 
    return (nil, isOrgType) 
    } 
    return (firstChild.value as? T, isOrgType) 
} 

let value: [Int]? = [0] 
let value2: [Int]? = nil 

let anyValue: Any = value 
let anyValue2: Any = value2 

let unwrappedResult:([Int]?, Bool) 
    = unwrap(value: anyValue) // ({[0]}, .1 true) 
let unwrappedResult2:([Int]?, Bool) 
    = unwrap(value: anyValue2) // (nil, .1 true) 
let unwrappedResult3:([UInt]?, Bool) 
    = unwrap(value: anyValue) // (nil, .1 false) 
let unwrappedResult4:([NSNumber]?, Bool) 
    = unwrap(value: anyValue) ({[0]}, .1 false) 

Sau đây là mã trên Sân chơi.

enter image description here

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