在Swift 3中,比较两个闭包的方法是什么? [英] In Swift 3, what is a way to compare two closures?

查看:147
本文介绍了在Swift 3中,比较两个闭包的方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Suppose you have two closures of type (Int)->() in Swift 3 and test to see if they are the same as each other:

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

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

此操作无法编译,显示以下消息:

This fails to compile, giving the message:


二进制运算符'=='不能应用于两个'(Int)->()'操作数

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

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

OK, well, how then can we compare two closures of the same type, to see if they are the same?

推荐答案

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

I'm pretty sure there is no way to determine if two closures are equal.

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

Obviously, a logical equality check is out of the question. That would be equivalent to finding an answer to the halting problem. (Just test to see if your code is equivalent to a piece of code that loops forever. If it is, it doesn't halt. If it isn't, it does halt.)

理论上,您可能希望 === 运算符测试两个闭包是否完全相同,但在尝试时会出现错误在操场上。

In theory you might expect the === operator to test if two closures are the exact same piece of code, but that gives an error when I try it in 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
          ~~~~~~~~ ^   ~~~~~~~~

考虑到这一点,我确定之所以行不通的原因是因为您无法确定闭包是否真正相等。闭包不仅是代码,而且是创建它的上下文(包括所有捕获)。您无法检查是否相等的原因是,没有两个闭包相等的有意义的方式。

Having thought about it, I'm sure the reason why that doesn't work is because you can't be sure that the closures really are equal. A closure is not just the code, but also the context in which it was created including any captures. The reason you can't check for equality is that there is no meaningful way in which two closures are equal.

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

To understand why thew captures are important, look at the following code.

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

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

Are closure1 closure2 是否相等?它们都使用相同的代码块

Are closure1 and closure2 equal? They both use the same block of code

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

所以它们不相等。您可能会争辩说可以检查代码是否相同并且捕获的内容是否相同,但是

So they are not equal. You could argue that you can check the code is the same and the captures are the same, but what about

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甚至没有尝试过。这比提供某些情况下错误的不完整实现要安全得多。

Apparently these closures are equal. It's not possible to implement any reasonable definition of equality that will work in every case, so Apple has instead not even tried. This is safer than providing an incomplete implementation that is wrong in some cases.

这篇关于在Swift 3中,比较两个闭包的方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆