我正在使用标准库提供的协议尝试一些非常棘手的事情。基本上,在以下代码中,A和B是来自标准库的协议。我想实现一种“特殊”类型的B(在下面的代码中命名为C),它比常规B更聪明,我想创建一个可以使用B或C的A的实现,当提供B时会使用默认行为,而当提供C时会使用更聪明的行为。但是,C也必然使用Self。
这个代码是我想要做的,但它不起作用。它可以用作实验的游乐场。
protocol A {
associatedtype T: B
func lookAt(thing: B) -> String
}
protocol B {
}
protocol C: B {
static var someThing: Self { get }
}
extension B {
func beSmart() -> String { return "I am a stupid B" }
}
extension C {
func beSmart() -> String { return "I am a clever C" }
}
struct AImplementation<T: B> {
func lookAt(thing: T) -> String {
return "A \(String(describing: T.self)) says: \(thing.beSmart())"
}
}
struct BImplementation: B {
}
struct CImplementation: C {
static let someThing = CImplementation()
}
let AimplWithB = AImplementation<BImplementation>()
AimplWithB.lookAt(thing: BImplementation())
let AimplWithC = AImplementation<CImplementation>()
AimplWithC.lookAt(thing: CImplementation())
这应该导致文本“A BImplementation说:我是一个愚蠢的B”和“一个CImplementation说:我是一个聪明的C”。
然而,它目前会说“A BImplementation说:我是一个愚蠢的B”和“一个CImplementation说:我是一个愚蠢的B”。
调用beSmart()
时可以使用正确的类型,但显然Swift无法确定要调用哪个beSmart()
。是否有一些方法可以使这些代码按预期工作,而不需要触及协议A或B,并让C使用Self?
答案 0 :(得分:-1)
我认为编译器没有足够的信息来查找beSmart()实现的路径,因为它不在B协议的公开方法中。
如果您将其添加到协议中,您的扩展程序将&#34; connect&#34;并且还充当默认实现,以便实现协议的类不必定义函数。
protocol B {
func beSmart() -> String
}