swift - 在 Swift 3 中,比较两个闭包的方法是什么?

标签 swift compare comparison closures

假设您在 Swift 3 中有两个 (Int)->() 类型的闭包,并测试它们是否彼此相同:

typealias Baz = (Int)->()
let closure1:Baz = { print("foo \($0)") }
let closure2:Baz = { print("bar \($0)") }

if(closure1 == closure2) {
    print("equal")
}

编译失败,提示信息:

Binary operator '==' cannot be applied to two '(Int)->()' operands

好的,那么我们如何比较相同类型的两个闭包,看看它们是否相同?

最佳答案

我很确定没有办法确定两个闭包是否相等。

显然,逻辑相等性检查是不可能的。这相当于找到停机问题的答案。 (只需测试一下您的代码是否等同于一段永远循环的代码。如果是,它不会停止。如果不是,它会停止。)

理论上,您可能希望 === 运算符测试两个闭包是否是完全相同的代码段,但是当我在 Playground 中尝试时会出现错误。

Playground execution failed: error: MyPlayground.playground:1:20: error: cannot check reference equality of functions; operands here have types '(Int) ->  ()' and '(Int) -> ()'
let bar = closure1 === closure2
          ~~~~~~~~ ^   ~~~~~~~~

考虑之后,我确定这不起作用的原因是因为您无法确定闭包是否真的相等。闭包不仅仅是代码,还包括创建它的上下文,包括任何捕获。您无法检查相等性的原因是没有有意义的方式使两个闭包相等。

要了解为什么捕获很重要,请查看以下代码。

func giveMeClosure(aString: String) -> () -> String
{
     return { "returning " + aString }
}

let closure1 = giveMeClosure(aString: "foo")
let closure2 = giveMeClosure(aString: "bar")

closure1closure2 是否相等?他们都使用相同的代码块

print(closure1()) // prints "returning foo"
print(closure2()) // prints "returning bar"

所以他们不相等。您可能会争辩说您可以检查代码是否相同并且捕获是否相同,但是怎么样

func giveMeACount(aString: String) -> () -> Int
{
    return { aString.characters.count }
}

let closure3 = giveMeACount(aString: "foo")
let closure4 = giveMeACount(aString: "bar")

print(closure3()) // prints 3
print(closure4()) // prints 3

显然这些闭包是相等的。不可能实现任何适用于所有情况的合理的平等定义,因此 Apple 甚至没有尝试过。这比在某些情况下提供错误的不完整实现更安全。

关于swift - 在 Swift 3 中,比较两个闭包的方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45270371/

相关文章:

objective-c - Swift 的 Array 类型桥接到 Foundation 的 NSArray 类,如何?

swift - 在 ScrollView 中缩放/滚动部分图像

sql-server - T-SQL IS NOT NULL 与 NOT NULL 性能

programming-languages - 什么是 'Language Performance' ?

iOS swift 3 : Comparing One all elements of Array in another array

ios - 日期之间的提醒问题

python - 比较两个字符串,包括重复的字母?

php - 创建 php 文件以从某些本地服务器同步 mysql 数据

c - 超越比较 : compare whole function calls or xml blocks

c - 两个 block 的字典顺序比较