swift - 没有大括号和参数标签的匿名函数?
问题描述
我在另一个问题上看到了一些代码,它似乎用一些不寻常的语法创建了一个匿名函数(闭包表达式):
let plus: (Int, Int) -> Int = (+)
我理解左边——它声明了一个类型的常量(Int, Int) -> Int
(一个接受两个整数并返回一个整数的函数)。但什么是(+)
?它如何声明一个没有大括号的函数,以及当没有任何类型的参数标签时它如何引用两个参数?
该函数接受两个参数,将它们相加,然后返回结果。如果我用+
不同的操作符(比如 a *
)替换操作符,操作就会改变。那么它是某种速记{$0 + $1}
吗?如果是这样,这个速记背后的逻辑是什么?
解决方案
实际上,这不是简写。
plus
是一个类型的变量(Int, Int) -> Int
。您可以将任何属于此类型(或其任何子类型)的对象分配给它。文字 lambda 闭包当然属于这种类型,但实际上命名函数或方法也可以。这正是这里正在发生的事情。
它正在将命名的运算符方法对象分配给+
变量。
在语言指南的闭包章节中隐含地提到了这一点:
运算符方法
实际上有一种更短的方法来编写上面的闭包表达式。Swift 的
String
类型将其大于运算符 (>
) 的特定于字符串的实现定义为具有两个 type 参数String
并返回 type 值的方法Bool
。这与方法所需的方法类型完全匹配sorted(by:)
。因此,您可以简单地传入大于运算符,Swift 会推断您想要使用其特定于字符串的实现:reversedNames = names.sorted(by: >)
因此,代码所做的是将Operator Method+
分配给变量plus
。+
只是分配给变量的函数的名称。不涉及魔术速记。
看到这个你会惊讶吗?
let plus: (Int, Int) -> Int = foo
推荐阅读
- angular - OL 6.5.0,同一点图中的许多 LineString 会导致速度变慢
- python - 如何在 Calendly 中正确使用页面令牌进行迭代?
- python - 使用类似架构掩码的 u-net 进行图像分割时出错不起作用
- arrays - 在 mongoldb 中使用聚合管道弹出最后一个数组元素
- c# - MySqlCommand.Parameters.Add 在 c# 中的命令文本中添加斜杠
- json - 如何使用 JQ 减少 JSON 的值长度
- r - 如何根据某些条件匹配 R 中的项目?
- google-cloud-platform - 从 linux 谷歌云服务器下载文件到我的电脑
- python - 乌龟没有反应
- python - 不同维度张量的乘法