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 咖啡时间的更多相关文章

  1. Swift 3 新特性和迁移详解

    写在前面 Swift 3.0 正式版发布了差不多快一个月了,断断续续的把手上和 Swift 相关的迁移到了Swift 3.0.所以写点小总结. 背景 代码量(4万行) 首先,我是今年年初才开始入手 S ...

  2. 视频特性TI(时间信息)和SI(空间信息)的计算工具:TIandSI-压缩码流版

    ===================================================== TI(时间信息)和SI(空间信息)计算工具文章列表: 视频特性TI(时间信息)和SI(空间信 ...

  3. Atitit.swift 的新特性 以及与java的对比 改进方向attilax 总结

    Atitit.swift 的新特性 以及与java的对比 改进方向attilax 总结 1. defer关键字1 2. try!形式存在的“不失败”机制3 3. Guard 4 4. swift的新语 ...

  4. 发现意外之美 - SwiftyJSON 源码学习 | 咖啡时间

    SwiftyJSON 是一个很优秀 Swift 语言第三方库.我们在之前的文章中对它有过介绍.相信大家对它也有了一些了解.提升开发功力最好的方式就是学习优秀的源代码了,记得大神 TJ Holowayc ...

  5. Swift 3 新特性

    原文:What's New in Swift 3? ,作者:Ben Morrow,译者:kmyhy Swift 3将于今年下半年推出,为Swift开发者们带来了很多核心代码的改变.如果你没有关注过 S ...

  6. iOS - Swift Swift 语言新特性

    1.Swift 2.0 带来哪些新变化 常规变化: 1.OS X 10.11.iOS 9 和 watchOS 2 SDK 采纳了一些 Objective-C 的特性用来提高 Swift 的编程体验, ...

  7. 最全的 Swift 4 新特性解析

    转自: http://www.jianshu.com/p/f35514ae9c1a WWDC 2017 带来了很多惊喜.Swift 4 也伴随着 Xcode 9 测试版来到了我们的面前,很多强大的新特 ...

  8. Swift 4 新特性

    多行字符串 /// 多行字符串用三引号括起来 let quotation = """ The White Rabbit put on his spectacles. &q ...

  9. swift 3新特性总结

    swift新特性之String 参考自[Swift 3.0 变化汇总系列总结-String] 使用方法:直接CMD+F搜索相应的函数或关键字符串,比较修改代码. 重要: /// 使用String的方法 ...

随机推荐

  1. AVR第5课:蜂鸣器

    下面是蜂鸣器的电路图. 代码:蜂鸣器代码. <span style="font-size:18px;">/* *info:buzzer *author:chenlu * ...

  2. 百度地图坐标之间的距离php

    function GetDistance($lat1, $lng1, $lat2, $lng2){ define('PI',3.1415926535898); define('EARTH_RADIUS ...

  3. linux中竖线'|',双竖线‘||’,&和&&的意思

    对于初学者来说这几个意思可能只知道其中几个的意思,下面我们来看一下. 1.竖线'|' ,在linux中是作为管道符的,将'|'前面命令的输出作为'|'后面的输入.举个例子 [18066609@root ...

  4. 注册表 Run、RunOnce 浅析

    绝大多数使用过 Windows 操作系统的用户都不会对注册表的 Run.RunOnce 键值感到陌生,但你真的了解所有这些键值的细节吗?让我们具体说来. 本文在Win2000,WinXp.Vista. ...

  5. 【codeforces 757C】Felicity is Coming!

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  6. NOIP模拟 赌博游戏 - 概率dp

    题意: 最近西雅图的高中校园里流行这样一个游戏. 我们有一个骰子,这个骰子有M个面,分别写着1..M,并且是个公平的骰子,换句话说,一次投掷时每个面朝上的概率是相同的. 游戏的组织者使用这个骰子进行N ...

  7. 前端,Java,产品经理,微信小程序,Python等资源合集大放送

    为了感恩大家长久以来的关注和支持,小编准备了一些福利,整理了包含前端,Java,产品经理,微信小程序,Python,网站源码,Android应用视频教程,微信公众平台开发教程及材料等资源合集大放送. ...

  8. PatentTips - Heterogeneous Parallel Primitives Programming Model

    BACKGROUND 1. Field of the Invention The present invention relates generally to a programming model ...

  9. BZOJ 1864 三色二叉树 - 树型dp

    传送门 题目大意: 给一颗二叉树染色红绿蓝,父亲和儿子颜色必须不同,两个儿子颜色必须不同,问最多和最少能染多少个绿色的. 题目分析: 裸的树型dp:\(dp[u][col][type]\)表示u节点染 ...

  10. NOIP模拟 - 树

    题目描述 给出一张n个点,m条边的无向图,摧毁每条边都需要一定的体力,并且花费的体力值各不相同,给定图中两个点x,y(x≠y),每当(x,y)之间存在路径,就需要不断摧毁当前图中花费体力最少的一条边, ...