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

相关文章

SpringCloud Stream 快速入门实例教程

《SpringCloudStream快速入门实例教程》本文介绍了SpringCloudStream(SCS)组件在分布式系统中的作用,以及如何集成到SpringBoot项目中,通过SCS,可... 目录1.SCS 组件的出现的背景和作用2.SCS 集成srping Boot项目3.Yml 配置4.Sprin

SpringMVC配置、映射与参数处理​入门案例详解

《SpringMVC配置、映射与参数处理​入门案例详解》文章介绍了SpringMVC框架的基本概念和使用方法,包括如何配置和编写Controller、设置请求映射规则、使用RestFul风格、获取请求... 目录1.SpringMVC概述2.入门案例①导入相关依赖②配置web.XML③配置SpringMVC

MySQL索引踩坑合集从入门到精通

《MySQL索引踩坑合集从入门到精通》本文详细介绍了MySQL索引的使用,包括索引的类型、创建、使用、优化技巧及最佳实践,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友... 目录mysql索引完整教程:从入门到入土(附实战踩坑指南)一、索引是什么?为什么需要它?1.1 什么

Java Lettuce 客户端入门到生产的实现步骤

《JavaLettuce客户端入门到生产的实现步骤》本文主要介绍了JavaLettuce客户端入门到生产的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 目录1 安装依赖MavenGradle2 最小化连接示例3 核心特性速览4 生产环境配置建议5 常见问题

从基础到高级详解Go语言中错误处理的实践指南

《从基础到高级详解Go语言中错误处理的实践指南》Go语言采用了一种独特而明确的错误处理哲学,与其他主流编程语言形成鲜明对比,本文将为大家详细介绍Go语言中错误处理详细方法,希望对大家有所帮助... 目录1 Go 错误处理哲学与核心机制1.1 错误接口设计1.2 错误与异常的区别2 错误创建与检查2.1 基础

Python函数作用域与闭包举例深度解析

《Python函数作用域与闭包举例深度解析》Python函数的作用域规则和闭包是编程中的关键概念,它们决定了变量的访问和生命周期,:本文主要介绍Python函数作用域与闭包的相关资料,文中通过代码... 目录1. 基础作用域访问示例1:访问全局变量示例2:访问外层函数变量2. 闭包基础示例3:简单闭包示例4

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 中手