IOS Swift 从入门到精通:闭包第二部分,高级闭包

2024-06-23 06:52

本文主要是介绍IOS Swift 从入门到精通:闭包第二部分,高级闭包,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 当闭包接受参数时使用闭包作为参数
  • 当闭包返回值时使用闭包作为参数
  • 简写参数名称
  • 高级闭包: 具有多个参数的闭包
  • 高级闭包:从函数返回闭包
  • 高级闭包:捕获值
  • 总结

当闭包接受参数时使用闭包作为参数

这是闭包开始变得有点像线路噪声的地方:传递给函数的闭包也可以接受它自己的参数。

我们一直使用() -> Void它来表示“不接受任何参数并且不返回任何内容”,但是您可以继续填充()闭包应该接受的任何参数的类型。

为了证明这一点,我们可以编写一个travel()接受闭包作为其唯一参数的函数,并且该闭包又接受一个字符串:

func travel(action: (String) -> Void) {print("I'm getting ready to go.")action("London")print("I arrived!")
}

现在,当我们travel()使用尾随闭包语法调用时,我们的闭包代码需要接受一个字符串:

 travel { (place: String) inprint("I'm going to \(place) in my car") }

当闭包返回值时使用闭包作为参数

我们一直使用() -> Void它来表示“不接受任何参数并且不返回任何内容”,但是您可以Void用任何类型的数据替换它以强制闭包返回一个值。

为了证明这一点,我们可以编写一个travel()接受闭包作为其唯一参数的函数,而该闭包又接受一个字符串并返回一个字符串:

func travel(action: (String) -> String) {print("I'm getting ready to go.")let description = action("London")print(description)print("I arrived!")
}

现在,当我们travel()使用尾随闭包语法调用时,我们的闭包代码需要接受一个字符串并返回一个字符串:

travel { (place: String) -> String inreturn "I'm going to \(place) in my car"
}

简写参数名称

我们刚刚创建了一个travel()函数。它接受一个参数,这是一个闭包,它本身接受一个参数并返回一个字符串。然后该闭包在两次调用之间运行print()。

代码如下:

func travel(action: (String) -> String) {print("I'm getting ready to go.")let description = action("London")print(description)print("I arrived!")
}

我们可以travel()使用如下方法调用:

travel { (place: String) -> String inreturn "I'm going to \(place) in my car"
}

但是,Swift知道该闭包的参数必须是字符串,因此我们可以将其删除:

travel { place -> String inreturn "I'm going to \(place) in my car"
}

它还知道闭包必须返回一个字符串,所以我们可以删除它:

travel { place inreturn "I'm going to \(place) in my car"
}

由于闭包只有一行代码,并且必须是返回值的代码,所以 Swiftreturn也允许我们删除关键字:

travel { place in"I'm going to \(place) in my car"
}

Swift 有一个简写语法,可以让你写得更简洁。我们可以让 Swift 自动为闭包的参数提供名称,而不是直接书写place in。这些参数以美元符号命名,然后是一个从 0 开始的数字。

travel {"I'm going to \($0) in my car"
}

高级闭包: 具有多个参数的闭包

为了确保一切都清楚,我们将使用两个参数编写另一个闭包示例。

这次我们的travel()函数需要一个闭包来指定某人要去的地方以及他们要行驶的速度。这意味着我们需要使用(String, Int) -> String参数的类型:

func travel(action: (String, Int) -> String) {print("I'm getting ready to go.")let description = action("London", 60)print(description)print("I arrived!")
}

我们将使用尾随闭包和简写闭包参数名称来调用它。因为这接受两个参数,所以我们将同时获取$0和$1:

travel {"I'm going to \($0) at \($1) miles per hour."
}

有些人不喜欢使用简写参数名称,$0因为它可能会造成混淆,但这没关系 - 只要对您来说最有效就行。

高级闭包:从函数返回闭包

就像你可以将闭包传递给函数一样,你也可以从函数获取返回的闭包。

这个语法首先有点令人困惑,因为它使用了->两次:一次用于指定函数的返回值,第二次用于指定闭包的返回值。

为了尝试这一点,我们将编写一个travel()不接受任何参数但返回闭包的函数。返回的闭包必须使用字符串调用,并且不会返回任何内容。

在 Swift 中它看起来是这样的:

func travel() -> (String) -> Void {return {print("I'm going to \($0)")}
}

我们现在可以调用travel()来取回该闭包,然后将其作为函数调用:

let result = travel()
result("London")

从技术上讲,直接调用返回值是允许的(尽管并不推荐!)travel():

let result2 = travel()("London")

高级闭包:捕获值

如果在闭包中使用任何外部值,Swift会捕获它们 - 将它们与闭包一起存储,这样即使它们不再存在也可以对其进行修改。

现在我们有一个travel()返回闭包的函数,返回的闭包接受一个字符串作为其唯一参数并且不返回任何内容:

func travel() -> (String) -> Void {return {print("I'm going to \($0)")}
}

我们可以调用travel()来取回闭包,然后自由地调用该闭包:

let result = travel()
result("London")

如果我们创建在travel()闭包内部使用的值,就会发生闭包捕获。例如,我们可能想要跟踪返回的闭包被调用的频率:

func travel() -> (String) -> Void {var counter = 1return {print("\(counter). I'm going to \($0)")counter += 1}
}

即使该counter变量是在内部创建的travel(),它也会被闭包捕获,因此它仍然会对该闭包保持有效。

因此,如果我们result(“London”)多次调用,计数器就会不断增加:

result("London")
result("London")
result("London")

总结

  • 您可以将闭包分配给变量,然后稍后调用它们。
  • 闭包可以接受参数并返回值,就像常规函数一样。
  • 您可以将闭包作为参数传递给函数,并且这些闭包可以具有自己的参数和返回值。
  • 如果函数的最后一个参数是闭包,则可以使用尾随闭包语法。
  • $0Swift 自动提供像和 这样的简写参数名称$1,但并不是每个人都使用它们。
  • 如果在闭包内部使用外部值,它们将被捕获,以便闭包稍后可以引用它们。

这篇关于IOS Swift 从入门到精通:闭包第二部分,高级闭包的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1086437

相关文章

Javascript高级程序设计(第四版)--学习记录之变量、内存

原始值与引用值 原始值:简单的数据即基础数据类型,按值访问。 引用值:由多个值构成的对象即复杂数据类型,按引用访问。 动态属性 对于引用值而言,可以随时添加、修改和删除其属性和方法。 let person = new Object();person.name = 'Jason';person.age = 42;console.log(person.name,person.age);//'J

C++必修:模版的入门到实践

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:C++学习 贝蒂的主页:Betty’s blog 1. 泛型编程 首先让我们来思考一个问题,如何实现一个交换函数? void swap(int& x, int& y){int tmp = x;x = y;y = tmp;} 相信大家很快就能写出上面这段代码,但是如果要求这个交换函数支持字符型

零基础STM32单片机编程入门(一)初识STM32单片机

文章目录 一.概要二.单片机型号命名规则三.STM32F103系统架构四.STM32F103C8T6单片机启动流程五.STM32F103C8T6单片机主要外设资源六.编程过程中芯片数据手册的作用1.单片机外设资源情况2.STM32单片机内部框图3.STM32单片机管脚图4.STM32单片机每个管脚可配功能5.单片机功耗数据6.FALSH编程时间,擦写次数7.I/O高低电平电压表格8.外设接口

iOS HTTPS证书不受信任解决办法

之前开发App的时候服务端使用的是自签名的证书,导致iOS开发过程中调用HTTPS接口时,证书不被信任 - (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAu

ps基础入门

1.基础      1.1新建文件      1.2创建指定形状      1.4移动工具          1.41移动画布中的任意元素          1.42移动画布          1.43修改画布大小          1.44修改图像大小      1.5框选工具      1.6矩形工具      1.7图层          1.71图层颜色修改          1

C++入门01

1、.h和.cpp 源文件 (.cpp)源文件是C++程序的实际实现代码文件,其中包含了具体的函数和类的定义、实现以及其他相关的代码。主要特点如下:实现代码: 源文件中包含了函数、类的具体实现代码,用于实现程序的功能。编译单元: 源文件通常是一个编译单元,即单独编译的基本单位。每个源文件都会经过编译器的处理,生成对应的目标文件。包含头文件: 源文件可以通过#include指令引入头文件,以使

android一键分享功能部分实现

为什么叫做部分实现呢,其实是我只实现一部分的分享。如新浪微博,那还有没去实现的是微信分享。还有一部分奇怪的问题:我QQ分享跟QQ空间的分享功能,我都没配置key那些都是原本集成就有的key也可以实现分享,谁清楚的麻烦详解下。 实现分享功能我们可以去www.mob.com这个网站集成。免费的,而且还有短信验证功能。等这分享研究完后就研究下短信验证功能。 开始实现步骤(新浪分享,以下是本人自己实现

LVGL快速入门笔记

目录 一、基础知识 1. 基础对象(lv_obj) 2. 基础对象的大小(size) 3. 基础对象的位置(position) 3.1 直接设置方式 3.2 参照父对象对齐 3.3 获取位置 4. 基础对象的盒子模型(border-box) 5. 基础对象的样式(styles) 5.1 样式的状态和部分 5.1.1 对象可以处于以下状态States的组合: 5.1.2 对象

C语言入门系列:探秘二级指针与多级指针的奇妙世界

文章目录 一,指针的回忆杀1,指针的概念2,指针的声明和赋值3,指针的使用3.1 直接给指针变量赋值3.2 通过*运算符读写指针指向的内存3.2.1 读3.2.2 写 二,二级指针详解1,定义2,示例说明3,二级指针与一级指针、普通变量的关系3.1,与一级指针的关系3.2,与普通变量的关系,示例说明 4,二级指针的常见用途5,二级指针扩展到多级指针 小结 C语言的学习之旅中,二级

打造坚固的SSH防护网:端口敲门入门指南

欢迎来到我的博客,代码的世界里,每一行都是一个故事 🎏:你只管努力,剩下的交给时间 🏠 :小破站 打造坚固的SSH防护网:端口敲门入门指南 前言什么是端口敲门端口敲门的优点1. 增强安全性2. 动态防火墙规则3. 隐匿服务4. 改善日志管理5. 灵活性和兼容性6. 低资源消耗7. 防御暴力破解和扫描8. 便于合法用户访问9. 适用于不同类型的服务 端口敲