在Swift

时间:2015-08-18 18:48:59

标签: swift generics optional

我正在摆弄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让我了解AnyObjectAny之后,@ 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),但这会产生上一个if discussed elsewhere中说明的相同问题。

所以它归结为:有没有人真的能够将任何东西投射到通用可选类型?在任何情况下?我很高兴接受任何有效的例子。

3 个答案:

答案 0 :(得分:3)

这真的不是关于仿制药;它是关于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],你就在同一条船上。

答案 1 :(得分:0)

到目前为止,我可以看到更新代码的目标是确定传递的参数(dict的值)是否为T类型。所以你错误地使用as?施放以检查类型。你真正想要的是“是”运营商。

swipeAdapterCallback

答案 2 :(得分:0)

现在按预期工作 - 在Playgrounds和项目中。