【Swift】学习笔记(七)——闭包

1、什么是闭包

闭包简单的来说就是匿名函数、lambdas函数 ,书面点的来说就是闭包是自包含的函数代码块,可以在代码中被传递和使用,可以捕获和存储其所在上下文中任意常量和变量的引用。 这就是所谓的闭合并包裹着这些常量和变量,俗称闭包。

2、闭包采取的形式

前面在函数文章中,都定义的是全局函数,以及内嵌函数 实际上都是闭包的一种特殊形式。

  • 全局函数一个有名字但不会捕获任何值的闭包
  • 嵌套函数一个有名字并可以捕获其封闭函数域内值的闭包
  • 闭包表达式是一个利用轻量级语法所写的可以捕获其上下文中变量或常量值的匿名闭包

4、全局函数和嵌套函数已经熟悉了,那来看下闭包表达式。

闭包表达式是一种利用简洁语法构建内联闭包的方式。它提供了一些语法优化,使得撰写闭包变得简单明了。下面来分析下它怎么简单明了。

5、示例:sorted函数Swift 标准库提供了sorted函数,会根据您提供的基于输出类型排序的闭包函数将已知类型数组中的值进行排序。 一旦排序完成,函数会返回一个与原数组大小相同的新数组,该数组中包含已经正确排序的同类型元素。

let names = ["Chris","Alex","Ewa","Barry","Daniella"]
func backwards(s1: String,s2: String) -> Bool {
    return s1 > s2
}
var reversed = sorted(names,backwards)
// reversed 为 ["Ewa","Daniella","Chris","Alex"]

sorted函数需要传入两个参数:

  • 已知类型的数组
  • 闭包函数,该闭包函数需要传入与数组类型相同的两个值,并返回一个布尔类型值来告诉sorted函数当排序结束后传入的第一个参数排在第二个参数前面还是后面。如果第一个参数值出现在第二个参数值前面,排序闭包函数需要返回true,反之返回false
闭包的一般表达式
{ (parameters) -> returnType in
    statements
}

那上面的调用方法可以优化成什么样子呢。
reversed = sorted(names,{ (s1: String,s2: String) -> Bool in
    return s1 > s2
})

in 关键字,他表示参数和返回值定义完成,函数体即将开始。


swift是一个参数类型确定的语言,它也能够推断参数类型。所以这里还可以这样写。

reversed = sorted(names,{ s1,s2 in return s1 > s2 } )


对于单表达式闭包,还可以隐藏return关键字。

reversed = sorted(names,s2 in s1 > s2 } )

Swift 自动为内联函数提供了参数名称缩写功能,您可以直接通过$0,$1$2来顺序调用闭包的参数。

reversed = sorted(names,{ $0 > $1 } )

还可以是用运算符函数

reversed = sorted(names,>)

不过说了这么多。可读性就被完全抹杀了。。。


那如果需要在闭包中输入很长的函数体,那就麻烦了。读起来不方便,所以就有了尾随闭包。闭包放在函数尾巴上。


那上面可以写成:

reversed = sorted(names) { $0 > $1 }


6、值捕获

闭包可以在其定义的上下文中捕获常量或变量。 即使定义这些常量和变量的原域已经不存在,闭包仍然可以在闭包函数体内引用和修改这些值。

func makeIncrementor(forIncrement amount: Int) -> () -> Int {
    var runningTotal = 0
    func incrementor() -> Int {
        runningTotal += amount
        return runningTotal
    }
    return incrementor
}

通过前面的接触,上面这个函数看懂了么。。。

这个函数接收一个叫forIncrement的外部参数名的Int参数,并返回一个()->Int 的函数类型。

在内嵌函数中没有接收runningTotal这个参数也能使用,就是内嵌函数捕获了包含它的函数体内的变量


闭包是引用类型

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...