是否可以在Swift中将变量或常量的类型设置为Protocol Equatable

时间:2018-12-16 15:37:45

标签: swift generics protocols

我是Swift的新手。我正在尝试做类似的事情:

let e:Equatable? where Equatable.Item == Int = nil

这可能吗?

此致

肖兹

2 个答案:

答案 0 :(得分:2)

简单的答案是,您不能基于协议创建变量。

如官方文档所述:

  

协议定义了方法,属性和其他方法的蓝图   适合特定任务或功能的要求。   该协议然后可以由类,结构或枚举采用   提供这些要求的实际执行情况。任意种类   满足协议要求的据说符合   该协议。

因此,开发人员需要进行的最少工作是创建符合某种协议的结构或类,例如Equatable

让我们再次以官方文档为例。 Equatable协议允许比较相同类型的两个元素,因此要实现此协议,需要实施==(lhs: Type, rhs: Type,)方法。

class StreetAddress {
    let number: String
    let street: String
    let unit: String?

    init(_ number: String, _ street: String, unit: String? = nil) {
        self.number = number
        self.street = street
        self.unit = unit
    }
}

extension StreetAddress: Equatable {
    static func == (lhs: StreetAddress, rhs: StreetAddress) -> Bool {
        return
            lhs.number == rhs.number &&
            lhs.street == rhs.street &&
            lhs.unit == rhs.unit
    }
}

现在只能根据您的谓词创建和比较两个StreetAddress的实例。

答案 1 :(得分:1)

只要所讨论的协议具有使用associatedType或使用Self的要求,就不能这样做。简而言之,它为编译器造成了太多歧义。等于表具有使用Self的要求。在不知道用例的情况下很难提出建议,但是在遇到这种情况的许多情况下,答案是将泛型提升到一个水平(例如,如果此行代码在函数内部,则使函数成为泛型)超过等于值,并使用通用类型):

func doSomething<T: Equatable>(with value: T?) { ... }

,或者查看type erasure。但是,如果我们对您的用例有更多了解,可能会更容易提出建议。