我正在研究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)
,但这会导致最后一个if
中说明的相同问题,在其他地方讨论过。所以问题就在于:有没有人真正将任何东西转换为通用可选类型?在任何情况下?如果有,我很乐意接受任何有效的示例。