符合协议(作为协议)

时间:2017-07-30 00:38:05

标签: swift protocols

假设我有一个协议Item,以及一个符合它的结构ConcreteItem

protocol Item {
    var name: String { get }
}

struct ConcreteItem: Item {
    let name: String
}

在某些时候,我希望有两套ConcreteItem

let set1 = Set([ConcreteItem(name: "item1")])
let set2 = Set([ConcreteItem(name: "item2"), ConcreteItem(name: "item1")])

我希望返回名为"item1"的项目。

我可以ConcreteItem符合HashableSet代码也可以使用。但是,让我说我也有以下内容:

struct AnotherConcreteItem: Item {
    let name: String
}

我希望AnotherConcreteItem仅仅因为符合Hashable而符合Item

然而,当我尝试实现这个想法时:

extension Item: Hashable {
    var hashValue: Int {
        return name.characters.count
    }
}

我收到以下错误:Extension of protocol 'Item' cannot have an inheritance clause

2 个答案:

答案 0 :(得分:0)

  

协议扩展'Item'不能有继承子句

此处的项目是协议,因此符合Hashable协议将无效。有关详细信息,请参阅here

答案 1 :(得分:0)

您尝试使用某些协议可能会做什么,但不是全部。如果您尝试遵循的协议没有任何关联类型或Self,则可以这样做。

示例:

protocol A {
    func foo()
}

protocol Item: A {
    var name: String { get }
}

struct ConcreteItem: Item {
    let name: String
}

extension Item {
    func foo() {

    }
}

符合Item的所有内容也符合A

但是,HashableSelf个约束。要符合Hashable,您还必须符合Equatable。为符合Equatable==的实现必须在具体类中,而不是其他协议,因为Equatable不能用作参数类型。你能做的最多就是这样:

protocol Item: Hashable {
    var name: String { get }
}

struct ConcreteItem: Item {
    let name: String
    // you need to implement == in every concrete class
    static func ==(lhs: ConcreteItem, rhs: ConcreteItem) -> Bool {
        return ...
    }
}

extension Item {
    var hashValue: Int {
        return name.characters.count
    }
}