Swift 的 Currying 特性 | SwiftCafe 咖啡时间
Currying 也是 Swift 的众多先进特性之一,用一句话说就是将接受多个参数的函数,转变成每次之接受一个参数的调用序列。
上面一句话说得可能大家感觉不是那么清楚,那么没关系,咱们举一个例子来说明吧。
比如,我们需要一个两个数字相加的函数,我们可以这样定义:
func add(a:Int, b:Int) -> Int {
return a + b
}
那么,我们直接这样调用,就可以得到结果了:
add(1, b: 2)
这个是最基本的使用角度,那么假如我们把思维提升一个层级,比如:
let numbers = 1...10
let added = numbers.map {
return add($0, b: 2)
}
这里我们先用 1...10
声明了一个整数数组,然后用它的 map
方法将数组中所有的元素都加 2 然后生成一个新的数组。
注: add($0, b: 2) 中的 $0 表示当前遍历到得数组元素,把它传递给 add 函数并且加 2 后返回,生成新的数组元素。
这样做好像也没什么问题,但实际上我们完全可以不使用闭包来处理 map
中的回调。我们还可以这样:
func add(a:Int) -> (Int -> Int) {
return { b in
return a + b
}
}
let numbers = 1...10
let added = numbers.map (add(2))
怎么样,有没有眼花缭乱呢? 怎么 map 函数调用变成这个样子的呢:numbers.map (add(2))
相信手机或电脑前的一定很聪明,能看出端倪。
实际上我们是把 add
函数的定义做了修改:
func add(a:Int) -> (Int -> Int)
我们的 add 函数现在只接受一个参数了。并且呢,注意一下它的返回值类型:
(Int -> Int)
在 Swift 中,这种定义格式,表示的是一个函数类型。也就是说,我们的 add
函数它除了接受一个 Int 类型的参数,它还会返回一个函数类型的闭包对象。
接着,再看看这个函数的实现:
func add(a:Int) -> (Int -> Int) {
return { b in
return a + b
}
}
确实,返回的是一个闭包对象,接受了一个参数 b,然后这个闭包对象,继续将 a 和 b 两个参数的值再次返回。
关于闭包的概念,可以参看咱们之前讨论过的文章:了解闭包
这么一来,就明了啦,add
函数其实是一个返回函数的函数。也可以把它看做一个函数生成器。它接受的参数作为它生成的函数的一个标准:
let addTwo = add(2)
let addThree = add(3)
let addFive = add(5)
就像上面的代码那样,给 add
函数传入不同的参数,它就会依照这个参数值,生成一个新的函数,而这个就会对它接受的参数与之前 add 指定的增量进行加法操作了。
嗯,绕了这么一大圈,我们刚才讨论的这种函数行为,就叫做 currying。
对于 add
函数呢,我们还可以有另外一种写法:
func add(a: Int)(b: Int) -> Int {
return a + b
}
这样写出来的 add
函数以,就显得直观一些了。
然后,我们依然可以像这样,用它来生成各种新的函数:
let addTwo = add(2)
let addThree = add(3)
let addFive = add(5)
还可以向这样,把它作为另一个回调的传入:
let numbers = 1...10
let added = numbers.map (add(2))
总之呢,Swift 诞生之初,就有着它先天的强大与灵活。
Swift 的 Currying 特性 | SwiftCafe 咖啡时间的更多相关文章
- Swift 3 新特性和迁移详解
写在前面 Swift 3.0 正式版发布了差不多快一个月了,断断续续的把手上和 Swift 相关的迁移到了Swift 3.0.所以写点小总结. 背景 代码量(4万行) 首先,我是今年年初才开始入手 S ...
- 视频特性TI(时间信息)和SI(空间信息)的计算工具:TIandSI-压缩码流版
===================================================== TI(时间信息)和SI(空间信息)计算工具文章列表: 视频特性TI(时间信息)和SI(空间信 ...
- Atitit.swift 的新特性 以及与java的对比 改进方向attilax 总结
Atitit.swift 的新特性 以及与java的对比 改进方向attilax 总结 1. defer关键字1 2. try!形式存在的“不失败”机制3 3. Guard 4 4. swift的新语 ...
- 发现意外之美 - SwiftyJSON 源码学习 | 咖啡时间
SwiftyJSON 是一个很优秀 Swift 语言第三方库.我们在之前的文章中对它有过介绍.相信大家对它也有了一些了解.提升开发功力最好的方式就是学习优秀的源代码了,记得大神 TJ Holowayc ...
- Swift 3 新特性
原文:What's New in Swift 3? ,作者:Ben Morrow,译者:kmyhy Swift 3将于今年下半年推出,为Swift开发者们带来了很多核心代码的改变.如果你没有关注过 S ...
- iOS - Swift Swift 语言新特性
1.Swift 2.0 带来哪些新变化 常规变化: 1.OS X 10.11.iOS 9 和 watchOS 2 SDK 采纳了一些 Objective-C 的特性用来提高 Swift 的编程体验, ...
- 最全的 Swift 4 新特性解析
转自: http://www.jianshu.com/p/f35514ae9c1a WWDC 2017 带来了很多惊喜.Swift 4 也伴随着 Xcode 9 测试版来到了我们的面前,很多强大的新特 ...
- Swift 4 新特性
多行字符串 /// 多行字符串用三引号括起来 let quotation = """ The White Rabbit put on his spectacles. &q ...
- swift 3新特性总结
swift新特性之String 参考自[Swift 3.0 变化汇总系列总结-String] 使用方法:直接CMD+F搜索相应的函数或关键字符串,比较修改代码. 重要: /// 使用String的方法 ...
随机推荐
- AVR第5课:蜂鸣器
下面是蜂鸣器的电路图. 代码:蜂鸣器代码. <span style="font-size:18px;">/* *info:buzzer *author:chenlu * ...
- 百度地图坐标之间的距离php
function GetDistance($lat1, $lng1, $lat2, $lng2){ define('PI',3.1415926535898); define('EARTH_RADIUS ...
- linux中竖线'|',双竖线‘||’,&和&&的意思
对于初学者来说这几个意思可能只知道其中几个的意思,下面我们来看一下. 1.竖线'|' ,在linux中是作为管道符的,将'|'前面命令的输出作为'|'后面的输入.举个例子 [18066609@root ...
- 注册表 Run、RunOnce 浅析
绝大多数使用过 Windows 操作系统的用户都不会对注册表的 Run.RunOnce 键值感到陌生,但你真的了解所有这些键值的细节吗?让我们具体说来. 本文在Win2000,WinXp.Vista. ...
- 【codeforces 757C】Felicity is Coming!
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- NOIP模拟 赌博游戏 - 概率dp
题意: 最近西雅图的高中校园里流行这样一个游戏. 我们有一个骰子,这个骰子有M个面,分别写着1..M,并且是个公平的骰子,换句话说,一次投掷时每个面朝上的概率是相同的. 游戏的组织者使用这个骰子进行N ...
- 前端,Java,产品经理,微信小程序,Python等资源合集大放送
为了感恩大家长久以来的关注和支持,小编准备了一些福利,整理了包含前端,Java,产品经理,微信小程序,Python,网站源码,Android应用视频教程,微信公众平台开发教程及材料等资源合集大放送. ...
- PatentTips - Heterogeneous Parallel Primitives Programming Model
BACKGROUND 1. Field of the Invention The present invention relates generally to a programming model ...
- BZOJ 1864 三色二叉树 - 树型dp
传送门 题目大意: 给一颗二叉树染色红绿蓝,父亲和儿子颜色必须不同,两个儿子颜色必须不同,问最多和最少能染多少个绿色的. 题目分析: 裸的树型dp:\(dp[u][col][type]\)表示u节点染 ...
- NOIP模拟 - 树
题目描述 给出一张n个点,m条边的无向图,摧毁每条边都需要一定的体力,并且花费的体力值各不相同,给定图中两个点x,y(x≠y),每当(x,y)之间存在路径,就需要不断摧毁当前图中花费体力最少的一条边, ...