条件和协议

时间:2017-10-15 16:23:33

标签: swift swift-protocols

我正在使用标准库提供的协议尝试一些非常棘手的事情。基本上,在以下代码中,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?

1 个答案:

答案 0 :(得分:-1)

我认为编译器没有足够的信息来查找beSmart()实现的路径,因为它不在B协议的公开方法中。

如果您将其添加到协议中,您的扩展程序将&#34; connect&#34;并且还充当默认实现,以便实现协议的类不必定义函数。

protocol B {
 func beSmart() -> String
}