当前位置: 首页 > 编程日记 > 正文

Swift:闭包

[objc] view plaincopy
print?在CODE上查看代码片派生到我的代码片
  1. /* 闭包(Closures) 
  2.  * 闭包是自包含的功能代码块,可以在代码中使用或者用来作为参数传值。 
  3.  * 在Swift中的闭包与C、OC中的blocks和其它编程语言(如Python)中的lambdas类似。 
  4.  * 闭包可以捕获和存储上下文中定义的的任何常量和变量的引用。这就是所谓的变量和变量的自封闭, 
  5.  * 因此命名为”闭包“("Closures)").Swift还会处理所有捕获的引用的内存管理。 
  6.  *  
  7.  * 全局函数和嵌套函数其实就是特殊的闭包。 
  8.  * 闭包的形式有: 
  9.  * (1)全局函数都是闭包,有名字但不能捕获任何值。 
  10.  * (2)嵌套函数都是闭包,且有名字,也能捕获封闭函数内的值。 
  11.  * (3)闭包表达式都是无名闭包,使用轻量级语法,可以根据上下文环境捕获值。 
  12.  *  
  13.  * Swift中的闭包有很多优化的地方: 
  14.  * (1)根据上下文推断参数和返回值类型 
  15.  * (2)从单行表达式闭包中隐式返回(也就是闭包体只有一行代码,可以省略return) 
  16.  * (3)可以使用简化参数名,如$0, $1(从0开始,表示第i个参数...) 
  17.  * (4)提供了尾随闭包语法(Trailing closure syntax) 
  18.  */  
  19.    
  20.  // 下面用Swift标准库中的sort方法来一步步简化闭包写法  
  21.  // sort函数需要两个参数  
  22.  // 参数一:数组  
  23.  // 参数二:一个闭包:带有两个参数,这两个参数类型与数组中的元素类型相同,返回值是Bool  
  24.  var names = ["Swift""Arial""Soga""Donary"]  
  25.    
  26.  // 第一种方式:使用函数  
  27.  func backwards(firstString: String, secondString: String) -> Bool {  
  28.    return firstString > secondString // 升序排序  
  29.  }  
  30.  // 这里第二个参数,传了一个函数  
  31.  // reversed is equal to ["Swift", "Soga", "Donary", "Arial"]  
  32.  var reversed = sort(nams, backwards)  
  33.    
  34.  // 第二种方式:使用闭包方式  
  35.  // 完整闭包写法是在花括号内有参数列表和返回值,用关键字in表明闭包体的开始  
  36.  // (firstString: String, secondString: String) 闭包参数列表  
  37.  // -> Bool 指明闭包返回值类型是Bool  
  38.  // in关键字表明闭包体的开始  
  39.  reversed = sort(names, { (firstString: String, secondString: String) -> Bool in  
  40.     return firstString > secondString  
  41.     })  
  42.   
  43.  // 这里可以进一步简化写法,因为闭包代码比较短,可以写到一行上  
  44.  reversed = sort(names, { (firstString: String, secondString: String) -> Bool in return firstString > secondString})  
  45.    
  46. // 下面再进一步简化写法 :根据环境上下文自动推断出类型  
  47. // 参数列表都没有指明类型,也没有指明返回值类型,这是因为swift可以根据上下文推测出  
  48. // firstString和secondString的类型会是names数组元素的类型,而返回值类型会根据return语句结果得到  
  49. reversed = sort(names, { firstString, secondString in return firstString > secondString})  
  50.   
  51. // 再进一步简化:隐式返回(单行语句闭包)  
  52. // 因为闭包体只有一行代码,可以省略return  
  53. reversed = sort(names, { firstString, secondString in firstString > secondString})  
  54.   
  55. // 再进一步简化:使用简化参数名($i,i=0,1,2...从0开始的)  
  56. // Swift会推断出闭包需要两个参数,类型与names数组元素相同  
  57. reversed = sort(names, { $0 > $1 })    
  58.   
  59. // 最简单的一种写法:使用操作符  
  60. reversed = sort(names, >)      
  61.       
  62.       
  63. /* 
  64.  * 尾随闭包(Trailing Closures) 
  65.  * 如果函数需要一个闭包参数作为参数,且这个参数是最后一个参数,而这个闭包表达式又很长时, 
  66.  * 使用尾随闭包是很有用的。尾随闭包可以放在函数参数列表外,也就是括号外。如果函数只有一个参数, 
  67.  * 那么可以把括号()省略掉,后面直接跟着闭包。 
  68.  */   
  69. // Array的方法map()就需要一个闭包作为参数  
  70. let strings = numbers.map { // map函数后面的()可以省略掉  
  71.   (var number) -> String in  
  72.   var output = ""  
  73.   while number > 0 {  
  74.     output = String(number % 10) + output   
  75.     number /= 10  
  76.   }  
  77.   return output  
  78. }  
  79.       
  80. /* 捕获值 
  81.  * 闭包可以根据环境上下文捕获到定义的常量和变量。闭包可以引用和修改这些捕获到的常量和变量, 
  82.  * 就算在原来的范围内定义为常量或者变量已经不再存在(很牛逼)。 
  83.  * 在Swift中闭包的最简单形式是嵌套函数。 
  84.  */   
  85. func increment(#amount: Int) -> (() -> Int) {  
  86.   var total = 0  
  87.   func incrementAmount() -> Int {  
  88.     total += amount // total是外部函数体内的变量,这里是可以捕获到的  
  89.     return total  
  90.   }  
  91.   return incrementAmount // 返回的是一个嵌套函数(闭包)  
  92. }     
  93.       
  94. // 闭包是引用类型,所以incrementByTen声明为常量也可以修改total  
  95. let incrementByTen = increment(amount: 10)   
  96. incrementByTen() // return 10,incrementByTen是一个闭包  
  97. // 这里是没有改变对increment的引用,所以会保存之前的值  
  98. incrementByTen() // return 20     
  99. incrementByTen() // return 30     
  100.   
  101. let incrementByOne = increment(amount: 1)  
  102. incrementByOne() // return 1  
  103. incrementByOne() // return 2      
  104. incrementByTen() // return 40   
  105. incrementByOne() // return 3  
  106.       
  107.       
  108.       

相关文章:

Ubuntu下使用CMake编译OpenSSL源码操作步骤(C语言)

OpenSSL的版本为1.0.1g,在ubuntu下通过CMake仅编译c代码不包括汇编代码,脚本内容如下: build.sh内容: #! /bin/bashreal_path$(realpath $0) dir_namedirname "${real_path}" echo "real_path: ${real_path}, di…

从词袋到Transfomer,NLP十年突破史

作者 | Zelros AI译者 | 夕颜出品 | AI科技大本营(ID:rgznai100)【导读】通过 Kaggle 竞赛视角,观察 NLP 十年发展简史。根据上下文(这里指句子的最后一个词),“它”可以指“动物”或“街道”。图源 | Goog…

《千只鹤》--[日]川端康成

《千只鹤》,作者是川端康成 故事梗概: 三谷菊治的父亲是个著名的茶道师匠,他生前与一位叫栗本近子的女人有染,后来又 钟情于太田夫人,而且由于后者而疏远了前者,但前者仍出入于三谷家。在三谷先生去 世四年…

所有接口添加plist文件的写法 swift

第一步 建立plist文件 interface JMTConfigUtils : NSObject /** * 获取配置文件中友盟key * * return NSString */ - (NSString *)umengKey; /** * 微信AppId * * return NSString */ - (NSString *)wxAppId; /** * 微信appSecret * * return NSString */ - (NSString…

提高C++性能的编程技术笔记:标准模板库+测试代码

标准模板库(Standard Template Library, STL)是容器和通用算法的强效组合。 渐近复杂度:算法的渐近复杂度是对算法性能的近似估计。它是算法集到特定性能标准集的映射。如果需要对包含N个整数的向量的所有元素求和,那么每个整数必须且仅需检查一次&…

「创式纪」人工智能应用创新大赛启动,首次结合商业计划和机器学习

谈到人工智能,技术和应用场景成为了大家广泛关注的话题。技术的演进,是推动人工智能发展的核心,而广泛的场景应用,则是人工智能真正价值所在。现阶段,精准营销、信贷风控、人脸比对等为人熟知的AI,已经经过…

linux chattr命令

chattr 设置linux文件的属性 (参照man手册进行翻译,常用的属性都翻译过来,个人觉得很少用到的属性就没有翻译) 用法:chattr [ -RVf ] -[acdeijstuADST] files选项:-R 对目录进行递归处理-V 显示详细的输出-F 忽略…

swift 中高德地图随时读取坐标地点的写法

自己写的方法 不比比 自己能看懂就行 只用作自己学习swift的总结 import UIKit typealias block (String,String) ->() class MoveCarViewController: UIViewController,MAMapViewDelegate,AMapLocationManagerDelegate,AMapSearchDelegate,UITextFieldDelegate,UIAler…

万字干货 | Python后台开发的高并发场景优化解决方案

嘉宾 | 黄思涵 来源 | AI科技大本营在线公开课互联网发展到今天,规模变得越来越大,也对所有的后端服务提出了更高的要求。在平时的工作中,我们或多或少都遇到过服务器压力过大问题。针对该问题,本次公开课邀请到了金山办公AI平台研…

提高C++性能的编程技术笔记:引用计数+测试代码

引用计数(reference counting):基本思想是将销毁对象的职责从客户端代码转移到对象本身。对象跟踪记录自身当前被引用的数目,在引用计数达到零时自行销毁。换句话说,对象不再被使用时自行销毁。 引用计数和执行速度之间的关系是与上下文紧密…

如何提升 CSS 选择器的性能?

CSS选择器对性能的影响源于浏览器匹配选择器和文档元素时所消耗的时间,所以优化选择器的原则是应尽量避免使用消耗更多匹配时间的选择器。而在这之前我们需要了解CSS选择器匹配的机制, 如子选择器规则: #header > a {font-weight:blod;} 我…

百度AI攻坚战:PaddlePaddle中国突围

作者 | 阿司匹林出品 | AI科技大本营(ID:rgznai100)2013年,百度开始研发深度学习框架PaddlePaddle,搜索、凤巢CTR预估上线DNN模型。2016年,在百度世界大会上,百度宣布PaddlePaddle开源&#xff…

提高C++性能的编程技术笔记:编码优化+测试代码

缓存:在现代处理器中,缓存经常与处理器中的数据缓存和指令缓存联系在一起。缓存主要用来存储使用频繁而且代价高昂的计算结果,这样就可以避免对这些结果的重复计算。如,循环内对常量表达式求值是一种常见的低性能问题。 预先计算…

Swift 中使用 SQLite——打开数据库

关于Swift中使用SQLite,接下来可能会分别从打开、增、删、改、查,几个方面来介绍SQLite的具体使用,这一篇重点介绍一下如何打开。 定义全局数据库访问句柄 /// 全局数据库访问句柄 private var db: COpaquePointer nil实现打开数据库函数 …

MVC中获取模型属性的Range和StringLength验证特性设置

MVC中的客户端及服务端模型验证信息都以ModelMetadata类型作为承载,在获得属性的ModelMetadata之后(还不知道怎么获取ModelMetadata的童鞋请自行恶补),我们可以轻松得到一些我们在模型中定义的特性,比如显示名称、是否…

以安装PyTorch为例说明Anaconda在Windows/Linux上的使用

在Windows10上配置完MXNet 1.3.0后,再配置PyTorch 1.0时,发现两者需要依赖的NumPy版本不一致,之前是通过pip安装NumPy,根据pip的版本不同,会安装不同版本的NumPy,使用起来很不方便,而且MXNet和P…

常用 SQL介绍

创建表 /*创建数据表CREATE TABLE 表名 (字段名 类型(INTEGER, REAL, TEXT, BLOB)NOT NULL 不允许为空PRIMARY KEY 主键AUTOINCREMENT 自增长,字段名2 类型,...)注意:在开发中,如果是从 Navicat 粘贴的 SQL,需要自己添加一个指令IF NO…

AttoNets,一种新型的更快、更高效边缘计算神经网络

作者 | Alexander Wong, Zhong Qiu Lin, and Brendan Chwyl 译者 | Rachel 出品 | AI科技大本营(ID:rgznai100)尽管机器学习已经在很多复杂的任务中取得了进展,但现有模型仍然面临许多边缘计算实践的困难,这些边缘计算场景包括移…

Appro DM8127 IPNC 挂载NFS遇到的问题及解决

对于Appro DM8127 IPNC,默认的启动方式是NAND is used for booting kernel and NAND is used as root filesystem 为了调试应用程序方便,通常使用挂载NFS作为 root filesystem 但是如果直接采用ti文档中所给的方法修改文件系统挂载方式(将启动…

提高C++性能的编程技术笔记:设计优化/可扩展性/系统体系结构相关+测试代码

1. 设计优化 我们可以粗略地将性能优化分为两种类型:编码优化和设计优化。编码优化定义为不需要完整理解要解决的问题或者应用程序的执行流程就能实施的优化。通过定义看出,编码优化用于局部代码,同时该过程不牵涉周围的代码。除了这些容易实…

ICLR 2020被爆半数审稿人无相关领域经验,同行评审制度在垮塌?

作者 | 若名出品 | AI科技大本营(ID:rgznai100)根据维基百科,同行评议(peer review),是指由一个或多个具有与作品生产者具有相似能力的人员(同行)对作品进行的评估活动。同行评审方法用于维持质…

Swift 中使用 SQLite——批量更新(事务处理)

本文是Swift 中使用 SQLite系列的收官之作,介绍一下在数据库中的批量更新。 事务 在准备做大规模数据操作前,首先开启一个事务,保存操作前的数据库的状态开始数据操作如果数据操作成功,提交事务,让数据库更新到数据操…

网络管理常用命令之二 - Ipconfig 命令详解(图文)

2、Ipconfig 命令...不带参数.../all 参数.../release 和 /realease6 参数.../Renew 和 /Renew6 参数.../flushdns 参数.../displaydns 参数2、Ipconfig 命令 ipconfig命令也是使用率非常高的一个命令,可用于显示系统的TCP/IP网络配置值,并刷新动态主…

Swift 中使用 SQLite——查询数据

本文主要介绍如何查询 SQLite 结果集,以及封装 SQLite 的操作方法。 准备测试代码 /// 从数据库中加载 person 数组 class func persons() -> [Person]? {// 1. 准备 SQLlet sql "SELECT id, name, age, height FROM T_Person;"// 2. 访问数据库// …

提高C++性能的编程技术笔记:总结

《提高C性能的编程技术》这本书是2011年出版的,书中有些内容的介绍可能已经过时,已不再适用于现在的C编程中,但大部分内容还是很有参考意义的。 这里是基于之前所有笔记的简单总结,笔记列表如下: 跟踪实例&#xff1…

13岁小孩都跟我抢Python了,完了!

以下来自一位程序员母亲和工作人员的对话。程序员妈妈:您好,可以帮我推荐一本适合我家小孩看的编程书籍吗?兔子:可以的呀,《Scratch从入门到精通》,这本书适合小孩学习,您可以先看一下哦~程序员…

Windows Mobile 6.0 SDK和中文模拟器下载

【转】 Windows Mobile 6.0 SDK和中文模拟器下载 Windows Mobile 6.5 模拟器2010年12月06日 星期一 07:48转载自 zhangyanle86终于编辑 zhangyanle86Windows Mobile 6.0 SDK和中文模拟器下载 SDK 6.0下载页面:http://www.microsoft.com/downloads/details.aspx?fam…

wxPython:Python首选的GUI库 | CSDN博文精选

作者 | 天元浪子来源 | CSDN博客文章目录概述窗口程序的基本框架事件和事件驱动菜单栏/工具栏/状态栏动态布局AUI布局DC绘图定时器和线程后记概述跨平台的GUI工具库,较为有名的当属GTK、Qt 和 wxWidgets 了。GTK是C实现的,由于C语言本身不支持OOP&#x…

Swift 中使用 SQLite——修改和删除数据

本文主要介绍在SQLite中修改数据、删除数据&#xff1a; 更新记录 /// 将当前对象信息更新到数据库 /// /// - returns: 是否成功 func updatePerson() -> Bool {guard let name name else {print("姓名不能为空")return false}if id < 0 {print("id 不…

用python3实现指定目录下文件sha256及文件大小统计

有时会统计某个目录下有哪些文件&#xff0c;每个文件的sha256及文件大小等相关信息&#xff0c;这里用python3写了个脚本用来实现此功能&#xff0c;此脚本可跨平台&#xff0c;同时支持windows和linux&#xff0c;脚本(get_dir_file_info.py)内容如下&#xff1a; import os…