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. 在shell脚本中调用sqlplus 分类: H2_ORACLE 2013-06-23 13:01 1437人阅读 评论(0) 收藏

    #!/bin/bash sqlplus dc_file_data_js/dc_file_data_js << EOF1 set linesize 500; set pagesize 100 ...

  2. TrustedBSD Mandatory Access Control Framework分析

    本文为CoryXie原创译文,转载及有任何问题请联系cory.xie#gmail.com. 本文分析FreeBSD 10.0[ http://xrefs.info/freebsd-10.0/ ]的MA ...

  3. [JS Compose] 6. Semigroup examples

    Let's we want to combine two account accidently have the same name. , friends: ['Franklin'] } , frie ...

  4. LeetCode -- 删除链表中值为k的元素

    本题目比較直接,一次遍历遇到匹配的元素直接删除(通过n.next = n.next.next)就能够了,仅仅是须要考虑到:1.首节点的情况2.末节点的情况 下面为实现: public ListNode ...

  5. C++ 工具类 —— 词条类(Entry)

    Entry 以键值对(key-value pair)的形式定义. template <typename K, typename V> struct Entry{ K key; V valu ...

  6. arm-linux内存管理学习笔记(1)-内存页表的硬件原理

    linux kernel集中了世界顶尖程序猿们的编程智慧,犹记操作系统课上老师讲操作系统的四大功能:进程调度 内存管理 设备驱动 网络.从事嵌入式软件开发工作,对设备驱动和网络接触的比較多. 而进程调 ...

  7. Python实战:如何隐藏自己的爬虫身份

    使用爬虫访问网站,需要尽可能的隐藏自己的身份,以防被服务器屏蔽,在工作工程中,我们有2种方式来实现这一目的,分别是延时访问和动态代理,接下来我们会对这两种方式进行讲解 1.延时访问 见名之意,延时访问 ...

  8. 关于java.lang.NoSuchMethodError: org.springframework.util.ReflectionUtils.makeAccessible

    <span style="font-size:18px;"> java.lang.NoSuchMethodError: org.springframework.util ...

  9. View的绘制顺序

    1.写在 super.onDraw() 的下面 把绘制代码写在 super.onDraw() 的下面,由于绘制代码会在原有内容绘制结束之后才执行,所以绘制内容就会盖住控件原来的内容. 2.写在 sup ...

  10. cordova-plugin-android-update安卓版本更新插件使用

    原文:cordova-plugin-android-update安卓版本更新插件使用 安装插件,使用方法官方都有. 安卓7.0以上要在AndroidMainfest.xml里加一句 <uses- ...