在Swift中转换为泛型可选

Seb*_*ian 6 generics optional 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")
}
Run Code Online (Sandbox Code Playgroud)

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

更新

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

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")
}
Run Code Online (Sandbox Code Playgroud)

第二次更新

@马特发后我了解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?'")
}
Run Code Online (Sandbox Code Playgroud)

我尝试使用init?(param: Any)之前,但其产生在最后示出的同样的问题if,其别处讨论.

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

Dar*_*rko 0

据我所知,您更新的代码的目标是查明传递的参数(字典的值)是否为 T 类型。所以您误用了 as ?强制转换以检查类型。您真正想要的是“is”运算符。

class SomeClass<T> {
    init?(v: [String: AnyObject]) {
        if v["k"] is T {
            print("called if AnyObject is of type T")
        } else {
            print("called if AnyObject is not of type T")
            return nil
        }
    }
}

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

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