我正在摆弄
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],你就在同一条船上.