如何使swift类符合某个协议,而该协议的属性之一要求使用符合协议的类型?

时间:2019-06-25 11:55:12

标签: swift

我试图使复杂的类层次结构符合协议,这有助于我重用代码片段。为此,我面临以下问题:类A具有属性b,这是类B的实例。B确实符合ProtocolB。现在,我想定义一个协议ProtocolA,以便A确实符合ProtocolA,并且ProtocolA指定类型ProtocolB的b。

这是我想出的:

class A {
    var b: B?
}

class B {}

protocol ProtocolA {
    var b: ProtocolB? { get }
}

protocol ProtocolB {}

extension B: ProtocolB {}
extension A: ProtocolA {}

不幸的是,XCode显示错误:

  

类型'A'不符合协议'ProtocolA'。

值得一提的是,我不能像这样直接定义类A和B:

class A: ProtocolA {
    var b: ProtocolB?
}

class B: ProtocolB {}

因为类A和B是由库预定义的。

2 个答案:

答案 0 :(得分:1)

您可以使用关联的类型。

ProtocolA中声明一个关联的类型:

protocol ProtocolA {
    associatedtype BType: ProtocolB
    var b: BType? { get } // Note the change in the type of b
}

这是说b是符合ProtocolB的某种可选类型。究竟是什么类型?这取决于ProtocolA的符合者。

A的扩展名中,指定BType是什么:

extension A: ProtocolA {
    typealias BType = B
}

您完成了!

结果,您将无法使用ProtocolA作为变量的类型:

var protocolA: ProtocolA? // error

因为您不知道b的类型。

答案 1 :(得分:0)

您可以使用associatedtype

class A {
    var b: B?
}

class B {}

protocol ProtocolA {
    associatedtype PB: ProtocolB
    var b: PB? { get }
}

protocol ProtocolB {}

extension B: ProtocolB {}
extension A: ProtocolA {}