我正在摆弄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
discussed elsewhere中说明的相同问题。
所以它归结为:有没有人真的能够将任何东西投射到通用可选类型?在任何情况下?我很高兴接受任何有效的例子。
答案 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和项目中。