Swift-闭包

前言

函数在 Swift 中是很强大的东西。可将函数分配给变量、将函数传递给函数,甚至从函数返回函数。

如:将函数分配给变量

scss 复制代码
func greetUser() {

    print("xxxxxxx!")

}

greetUser()    //调用函数

var greetCopy = greetUser    // 创建该函数的副本并调用该副本;复制函数时,不要在其后写括号

greetCopy() 

闭包表达式

当然,我们也可以不需要单独创建一个函数。所以:

scss 复制代码
let sayHello = {

    print("Hi xxxxxx!")

}

sayHello() 

我们可以随时传递和调用的一段代码。 它实际上是一个没有名称的,不带参数且不返回值的函数。

在Swift中,它叫 闭包表达式。

  • 带参数和返回值的闭包
rust 复制代码
let sayHello = { (name: String) -> String in

    "Hi \(name)!"

}  

其中,in是关键字,位于闭包的参数和返回类型之后。 in用于标记 参数和返回类型的结束,in之后的所有内容都是闭包本身的主体。

闭包在 Swift 中被广泛使用 。

从排序函数说起

数组的排序函数

ini 复制代码
let team = ["Gloria", "Suzanne", "Piper", "Tiffany", "Tasha"]

let sortedTeam = team.sorted()

print(sortedTeam)  

sorted()实际上允许我们 传递一个函数来创建自定义排序顺序,只要该函数 a) 接受两个字符串,b) 返回一个布尔值,sorted()就可以使用它。

好,先定义一个函数,作为sorted()的参数

swift 复制代码
func captainFirstSorted(name1: String, name2: String) -> Bool {

    if name1 == "Suzanne" {

        return true

    } else if name2 == "Suzanne" {

        return false

    }

    return name1 < name2
} 

传入

scss 复制代码
let arr = team.sorted(by: captainFirstSorted)

print(arr)  

以上都没有问题。

在Swift中,若A函数接受一个B函数作为参数,A函数并不关心传入的函数参数是一个创建的func,或一个闭包。

好的,让我们编写sorted()使用闭包进行调用的新代码:

kotlin 复制代码
let captainFirstTeam = team.sorted(by: { (name1: String, name2: String) -> Bool in

    if name1 == "Suzanne" {

        return true

    } else if name2 == "Suzanne" {

        return false

    }

    return name1 < name2

}) 

在这里,我们不是传递一个函数,而是传递一个闭包------------从by:到最后一行的)的所有内容都是闭包的一部分。

这样,我们不需要单独编写一个新函数了。

Swift 中闭包最常见的原因之一是存储功能------------"这是我希望你在某个时候做的一些工作,但不一定是现在。" 比如:延迟后运行一些代码。 动画完成后运行一些代码。 下载完成后运行一些代码。 当用户从菜单中选择一个选项时运行一些代码。
有了闭包,我们可以将一些功能包装在一个变量中,然后将其存储在某个地方。我们还可以从函数返回它,并将闭包存储在其他地方。

闭包语法

一个接受一个参数但不返回内容的闭包:

swift 复制代码
let payment = { (user: String) in

    print("Paying \(user)...")

} 

一个接受一个参数并返回一个布尔值的闭包:

rust 复制代码
let payment = { (user: String) -> Bool in

    print("Paying \(user)...")

    return true
}  

返回一个值而不接受任何参数

bash 复制代码
let payment = { () -> Bool in

    print("Paying an anonymous person...")

    return true

}  

尾随闭包和简洁语法

上述的sorted函数中,其实我们不需要指定两个参数的类型,因为它们必须是字符串,并且我们不需要指定返回类型,因为它必须是布尔值。因此,我们可以将代码重写为:

kotlin 复制代码
let captainFirstTeam = team.sorted { name1, name2 in

    if name1 == "Suzanne" {

        return true

    } else if name2 == "Suzanne" {

        return false

    }

    return name1 < name2

}  

另外, Swift 为我们提供的专门命名的值:$0和$1,分别用于第一个和第二个参数。 所以,我们甚至不需要指定参数了:

bash 复制代码
let captainFirstTeam = team.sorted {

    if $0 == "Suzanne" {

        return true

    } else if $1 == "Suzanne" {

        return false

    }

    return $0 < $1

}  

尾随闭包的 案例

scss 复制代码
func animate(duration: Double, animations: () -> Void) {

    print("Starting a \(duration) second animation...")

    animations()

}  

没有尾随闭包的情况下调用该函数,如下所示:

php 复制代码
animate(duration: 3, animations: {

    print("Fade out the image")

})  

用尾随闭包调用:

scss 复制代码
animate(duration: 3) {

    print("Fade out the image")

}  

代码简洁了许多

  • 函数接受多个函数参数,在这种情况下您可以指定多个尾随闭包。

这里有一个接受三个函数参数的函数,每个参数不接受任何参数,也不返回任何内容:

scss 复制代码
func doImportantWork(first: () -> Void, second: () -> Void, third: () -> Void) {
 
    first()

    second()

    third() 

} 

调用它时,第一个尾随闭包与我们已经使用过的相同,但第二个和第三个的格式不同:您结束前一个闭包的大括号,然后写入外部参数名称和冒号,然后开始另一个支撑。

bash 复制代码
doImportantWork {

    print("This is the first work")

} second: {

    print("This is the second work")

} third: {

    print("This is the third work")

} 
相关推荐
小poop6 小时前
CSS 基础与实战:从入门到精通网页美化
前端
Csvn8 小时前
运行时性能
前端
Never_every999 小时前
位图转矢量工具哪个好?实测抠抠图AI位图转矢量工具
大数据·前端
paopaokaka_luck9 小时前
宠物门店经营管理系统(销售与库存联动、进货自动记账、 退换与退款关联、员工个人业绩、ECharts 经营分析、滞销识别与客户分层、宠物档案年龄计算)
前端·javascript·spring boot·mysql·echarts·mybatis·1024程序员节
空中湖10 小时前
用 React 写数据大屏:为什么我不建议用图表库
前端·react.js·前端框架
欣欣之王来了11 小时前
原始HTML插值:v-html指令的使用与安全风险
前端·学习·架构·项目·vue3教程
IT_陈寒11 小时前
Redis的LRU淘汰策略坑了我一整天
前端·人工智能·后端
计算机魔术师11 小时前
砍半价格、参数再涨,国产旗舰追到 Opus 鼻尖了
前端
特立独行的猫A11 小时前
10 MB 的桌面 AI 客户端:用仓颉 + 系统 WebView 替代 Electron
前端·harmonyos
修炼的dance12 小时前
白底图存JPG,sharp开mozjpeg背景杂点少近三成
前端