微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在Swift中转换为泛型可选

我正在摆弄 Swift中的泛型并找到一些我无法弄清楚的东西:如果我将一个值转换为泛型参数的类型,则不会执行强制转换.如果我尝试使用静态类型,它可以工作.

class SomeClass<T> {
    init?() {
        if let _ = 4 as? T {
            println("should work")
        } else {
            return nil
        }
    }
}

if let _ = SomeClass<Int?>() {
    println("not called")
}

if let _ = 4 as? Int? {
    println("works")
}

任何人都可以解释这种行为吗?这两种情况不应该相同吗?

更新

以上示例简化为最大值.以下示例说明了需要更好的演员表

class SomeClass<T> {
    init?(v: [String: AnyObject]) {
        if let _ = v["k"] as? T? {
            print("should work")
        } else {
            print("does not")
            return nil
        }
    }
}

if let _ = SomeClass<Int?>(v: ["k": 4]) {
    print("not called")
}

if let _ = SomeClass<Int>(v: ["k": 4]) {
    print("called")
}

第二次更新

在@matt让我了解AnyObject和Any之后,@ Darko在他的评论中指出字典如何使我的例子过于复杂,这是我的下一个改进

class SomeClass<T> {
    private var value: T!

    init?<U>(param: U) {
        if let casted = param as? T {
            value = casted
        } else {
            return nil
        }
    }
}


if let _ = SomeClass<Int?>(param: Int(4)) {
    println("not called")
}

if let _ = SomeClass<Int>(param: Int(4)) {
    println("called")
}

if let _ = Int(4) as? Int? {
    println("works")
}

if let _ = (Int(4) as Any) as? Int? {
    println("Cannot downcast from Any to a more optional type 'Int?'")
}

我之前尝试过使用init?(param:Any),但是这会产生同样的问题,如果是discussed elsewhere则说明了.

所有这一切都归结为:有没有人真的能够将任何内容转换为通用可选类型?在任何情况下?我很高兴接受任何有效的例子.

解决方法

这根本不是关于泛型的;它是关于AnyObject(以及如何投射).考虑:

let d = ["k":1]
    let ok = d["k"] is Int?
    print (ok) // true

    // but:

    let d2 = d as [String:AnyObject]
    let ok2 = d2["k"] is Int?
    print (ok2) // false,though "is Int" succeeds

由于你的初始化程序将字典转换为[String:AnyObject],你就在同一条船上.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐