为什么swift编译器的行为与使用/不具有Equatable协议的相等运算符不同

时间:2017-11-01 16:18:54

标签: swift operator-overloading optional swift-protocols equatable

我在Swift 4.0的Playground中有一个非常简单的类,它覆盖了==运算符。

我不明白为什么当类继承/不继承 Equatable 协议时,Swift编译器的行为不一样。

继承Equatable协议时的类

class Test: Equatable  {
    var value = 0

    init(_ initialValue:Int) {
        value = initialValue
    }

    static func == (lhs:Test, rhs:Test) -> Bool {
        return lhs.value == rhs.value ? true : false
    }
}

let test1 = Test(0)
var test4:Test? = nil

if test1 == test4 {
    print("test1 and test4 are equals")
} else {
    print("test1 not equals to test4")
}

当此代码执行时,它显示“test1不等于test4”。这是预期的行为。

接下来,当我从类

中删除“Equatable”协议时
class Test  {
    var value = 0

    init(_ initialValue:Int) {
        value = initialValue
    }

    static func == (lhs:Test, rhs:Test) -> Bool {
        return lhs.value == rhs.value ? true : false
    }
}

let test1 = Test(0)
let test3 = Test(0)

var test4:Test? = nil


if test1 == test4 {
    print("test1 and test4 are equals")
} else {
    print("test1 not equals to test4")
}

我在行

上遇到编译错误
if test1 == test4 {

带有以下消息:“可选类型的值'测试?'没有打开;你的意思是使用“!”或“?”?

为什么在使用/不使用Equatable时行为会有所不同?

事实上,当类继承自Equatable时,我也期待同样的编译错误,因为我将非可选项与可选项进行比较。

当类继承Equatable时,将非可选项与可选项进行比较是否安全?

2 个答案:

答案 0 :(得分:1)

有一个== operator

data-name="3 years"

允许比较两个可选值(如果是底层) 类型为public func ==<T>(lhs: T?, rhs: T?) -> Bool where T : Equatable 在第一种情况下调用该运算符

Equatable

(左操作数自动包装成可选项。)

如果let test1 = Test(0) var test4:Test? = nil if test1 == test4 { ... } 不符合Test,那么该运营商会这样做 不匹配,因此没有Equatable运算符占用两个== 操作数。因此编译错误。

答案 1 :(得分:1)

如果您命令点击符合Equatable的那个,它会带您到这里:

g.run()

但是对于那些不符合Equatable的版本,你不会得到这个。它只会使用您提供的静态功能。