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中的高级调试方法全攻略指南

《JavaScript中的高级调试方法全攻略指南》什么是高级JavaScript调试技巧,它比console.log有何优势,如何使用断点调试定位问题,通过本文,我们将深入解答这些问题,带您从理论到实... 目录观点与案例结合观点1观点2观点3观点4观点5高级调试技巧详解实战案例断点调试:定位变量错误性能分

从入门到精通详解Python虚拟环境完全指南

《从入门到精通详解Python虚拟环境完全指南》Python虚拟环境是一个独立的Python运行环境,它允许你为不同的项目创建隔离的Python环境,下面小编就来和大家详细介绍一下吧... 目录什么是python虚拟环境一、使用venv创建和管理虚拟环境1.1 创建虚拟环境1.2 激活虚拟环境1.3 验证虚

从基础到高级详解Python数值格式化输出的完全指南

《从基础到高级详解Python数值格式化输出的完全指南》在数据分析、金融计算和科学报告领域,数值格式化是提升可读性和专业性的关键技术,本文将深入解析Python中数值格式化输出的相关方法,感兴趣的小伙... 目录引言:数值格式化的核心价值一、基础格式化方法1.1 三种核心格式化方式对比1.2 基础格式化示例

Android协程高级用法大全

《Android协程高级用法大全》这篇文章给大家介绍Android协程高级用法大全,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友跟随小编一起学习吧... 目录1️⃣ 协程作用域(CoroutineScope)与生命周期绑定Activity/Fragment 中手

深度解析Python yfinance的核心功能和高级用法

《深度解析Pythonyfinance的核心功能和高级用法》yfinance是一个功能强大且易于使用的Python库,用于从YahooFinance获取金融数据,本教程将深入探讨yfinance的核... 目录yfinance 深度解析教程 (python)1. 简介与安装1.1 什么是 yfinance?

Java List 使用举例(从入门到精通)

《JavaList使用举例(从入门到精通)》本文系统讲解JavaList,涵盖基础概念、核心特性、常用实现(如ArrayList、LinkedList)及性能对比,介绍创建、操作、遍历方法,结合实... 目录一、List 基础概念1.1 什么是 List?1.2 List 的核心特性1.3 List 家族成

c++日志库log4cplus快速入门小结

《c++日志库log4cplus快速入门小结》文章浏览阅读1.1w次,点赞9次,收藏44次。本文介绍Log4cplus,一种适用于C++的线程安全日志记录API,提供灵活的日志管理和配置控制。文章涵盖... 目录简介日志等级配置文件使用关于初始化使用示例总结参考资料简介log4j 用于Java,log4c

史上最全MybatisPlus从入门到精通

《史上最全MybatisPlus从入门到精通》MyBatis-Plus是MyBatis增强工具,简化开发并提升效率,支持自动映射表名/字段与实体类,提供条件构造器、多种查询方式(等值/范围/模糊/分页... 目录1.简介2.基础篇2.1.通用mapper接口操作2.2.通用service接口操作3.进阶篇3

MySQL数据类型与表操作全指南( 从基础到高级实践)

《MySQL数据类型与表操作全指南(从基础到高级实践)》本文详解MySQL数据类型分类(数值、日期/时间、字符串)及表操作(创建、修改、维护),涵盖优化技巧如数据类型选择、备份、分区,强调规范设计与... 目录mysql数据类型详解数值类型日期时间类型字符串类型表操作全解析创建表修改表结构添加列修改列删除列

Python自定义异常的全面指南(入门到实践)

《Python自定义异常的全面指南(入门到实践)》想象你正在开发一个银行系统,用户转账时余额不足,如果直接抛出ValueError,调用方很难区分是金额格式错误还是余额不足,这正是Python自定义异... 目录引言:为什么需要自定义异常一、异常基础:先搞懂python的异常体系1.1 异常是什么?1.2