为什么 swift 编译器的行为与相等运算符不同 with/without Equatable 协议
why swift compiler behaves differently with equality operator with/without Equatable protocol
我在 Swift 4.0 的 Playground 中有一个非常简单的 class,它覆盖了 == 运算符。
我不明白为什么 Swift 编译器在 class inherits/doesn 不继承 Equatable 时表现不同协议。
这里是继承Equatable协议时的class
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 not equals to test4"。这是预期的行为。
接下来,当我刚刚从 class
中删除 "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 {
带有以下消息:"Value of optional type 'Test?' not unwrapped; did you mean to use "!" 或 '?'?
为什么行为不同 with/without Equatable?
事实上,当 class 继承自 Equatable 时,我也期待同样的编译错误,因为我将非可选与可选进行比较。
当 class 继承 Equatable 时,比较非可选和可选是否安全?
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
则该运算符符合
不匹配,因此没有 ==
运算符取两个 Test?
操作数。因此编译错误。
如果您点击符合 Equatable 的命令,它将带您到这里:
/// ....
/// You can also use this OPERATOR TO COMPARE A NON-OPTIONAL VALUE TO AN
/// OPTIONAL that wraps the same type. The non-optional value is wrapped as an
/// optional before the comparison is made. In the following example, the
/// `numberToMatch` constant is wrapped as an optional before comparing to the
/// optional `numberFromString`:
///
/// let numberToFind: Int = 23
/// let numberFromString: Int? = Int("23") // Optional(23)
/// if numberToFind == numberFromString {
/// print("It's a match!")
/// }
/// // Prints "It's a match!"
///
/// ....
public func ==<T>(lhs: T?, rhs: T?) -> Bool where T : Equatable
但是对于不符合Equatable的版本,你不会得到这个。它只会使用您提供的静态函数。
我在 Swift 4.0 的 Playground 中有一个非常简单的 class,它覆盖了 == 运算符。
我不明白为什么 Swift 编译器在 class inherits/doesn 不继承 Equatable 时表现不同协议。
这里是继承Equatable协议时的class
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 not equals to test4"。这是预期的行为。
接下来,当我刚刚从 class
中删除 "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 {
带有以下消息:"Value of optional type 'Test?' not unwrapped; did you mean to use "!" 或 '?'?
为什么行为不同 with/without Equatable?
事实上,当 class 继承自 Equatable 时,我也期待同样的编译错误,因为我将非可选与可选进行比较。
当 class 继承 Equatable 时,比较非可选和可选是否安全?
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
则该运算符符合
不匹配,因此没有 ==
运算符取两个 Test?
操作数。因此编译错误。
如果您点击符合 Equatable 的命令,它将带您到这里:
/// ....
/// You can also use this OPERATOR TO COMPARE A NON-OPTIONAL VALUE TO AN
/// OPTIONAL that wraps the same type. The non-optional value is wrapped as an
/// optional before the comparison is made. In the following example, the
/// `numberToMatch` constant is wrapped as an optional before comparing to the
/// optional `numberFromString`:
///
/// let numberToFind: Int = 23
/// let numberFromString: Int? = Int("23") // Optional(23)
/// if numberToFind == numberFromString {
/// print("It's a match!")
/// }
/// // Prints "It's a match!"
///
/// ....
public func ==<T>(lhs: T?, rhs: T?) -> Bool where T : Equatable
但是对于不符合Equatable的版本,你不会得到这个。它只会使用您提供的静态函数。