我试图访问在协议扩展中定义的默认方法实现,该实现在实现中限制为类。 A'常规'声明工作正常,但是当我尝试转换为协议时,我无法访问协议上的默认定义方法,尽管类型满足where子句。
请考虑这个例子:
class Person {
var name: String
init(name: String) {
self.name = name
}
}
class Hero: Person {
var ability: String
init(name: String, ability: String) {
self.ability = ability
super.init(name: name)
}
}
class Pilot: Person {
var callSign: String
init(name: String, callSign: String) {
self.callSign = callSign
super.init(name: name)
}
}
class Programmer: Person {
var favoriteLanguage: String
init(name: String, favoriteLanguage: String) {
self.favoriteLanguage = favoriteLanguage
super.init(name: name)
}
}
// define a protocol
protocol PersonPresenter: class { }
// extend it where the conformer is a type of Person
extension PersonPresenter where Self: Person {
func displayName() {
print(name.uppercased())
}
}
// conform subclasses of Person to PersonPresenter
extension Hero: PersonPresenter { }
extension Pilot: PersonPresenter { }
extension Programmer: PersonPresenter { }
let myHero = Hero(name: "Hiro", ability: "Bend time & space")
myHero.displayName() // prints 'HIRO'
let myPilot = Pilot(name: "Pete", callSign: "Maverick")
myPilot.displayName() // prints 'PETE'
let myProgrammer = Programmer(name: "Chris", favoriteLanguage: "Swift")
myProgrammer.displayName() // prints 'CHRS'
let people: [Person] = [myHero,myPilot,myProgrammer]
if let presenter = people[0] as? PersonPresenter {
presenter.displayName() // Errror, PerseonPresenter is not a subtype of 'Person'
}
我想找到一种在满足where约束的同时强制转换为PersonPresenter的方法,以免被强制尝试转换为每个特定的子类来访问协议扩展的默认实现。或者不必使超类(可以在许多其他地方使用)符合协议。
答案 0 :(得分:1)
真正的问题是你正在扩展一个空协议。
通过强制转换为Hero,编译器知道它是Person的子类,然后它满足扩展约束。
但是当转换到协议PersonPresenter本身时,编译器不知道是否可以满足约束(作为Person)。
如果您在协议中声明要求,它将起作用:
protocol PersonPresenter: class {
func displayName()
}