在处理类及其子类的实例时,我遇到的似乎是一个强制转换异常,它们都被类型化为类符合的协议。
由于我不想将问题与我的域名的具体内容复杂化,我在下面给出了一个人为的例子来说明看似问题。
protocol P {
func canCast(_ p: P) -> Bool
}
extension P {
func canCast(_ p: P) -> Bool {
return p as? Self != nil
}
}
class X: P {}
class Y: X {}
let a: P = X()
let b: P = Y()
由于Y
是X
的子类,我们应该能够将b
投射到X
,但我们无法将a
投射到Y
print(a as? Y != nil) // prints false
print(b as? X != nil) // prints true
。
这很好,如下所示:
.canCast()
但是,当我使用协议中声明的print(b.canCast(a)) // prints true
print(a.canCast(b)) // prints true
方法时,两个强制转换似乎都成功了:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.example.com|www2\.example.com [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^/support/?$ http://example.com/site1/page1.html [R=301,NC,L]
我错过了什么吗?
答案 0 :(得分:1)
return p as? Self != nil
与
相同return p as? P != nil
答案 1 :(得分:0)
继@meggar发布的答案后,我做了一些工作,发现在这种情况下Self
始终表示符合协议的类型,而不是任何子类,无论方法是否在符合类或其任何子类的实例上调用。
因此,在这种情况下,
return p as? Self != nil
与
相同return p as? X != nil
对于X
的实例以及X
的任何子类的实例,此转换将成功,这就是在问题中显示的两种情况下都返回true
的原因。
为了证明这一点,我在协议扩展中向方法主体添加了一行,以打印self
的类型以及Self
所代表的类型。我还创建了一个新类Z
,它是Y
的子类。
下面给出了完整修改后的代码,其中显示Self
继续代表X
,无论是X
,Y
或Z
或self
(在每种情况下都是protocol P {
func canCast(_ p: P) -> Bool
}
extension P {
func canCast(_ p: P) -> Bool {
print("Type of self: \(type(of: self)), Self represents: \(Self.self)")
return p as? Self != nil
}
}
class X: P {}
class Y: X {}
class Z: Y {}
let a: P = X()
let b: P = Y()
let c: P = Z()
print(a.canCast(b))
// Type of self: X, Self represents: X
// true
print(b.canCast(a))
// Type of self: Y, Self represents: X
// true
print(c.canCast(a))
// Type of self: Z, Self represents: X
// true
的类型)。
let results : Results