【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", "Barry", "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, { s1, 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这个参数也能使用,就是内嵌函数捕获了包含它的函数体内的变量

闭包是引用类型

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-20 00:23:19

【Swift】学习笔记(七)——闭包的相关文章

Swift学习笔记七:闭包

闭包可以 捕获 和存储其所在上下文中任意常量和变量的引用. Swift 会为您管理在 捕获 过程中涉及到的内存操作. 在 函数 章节中介绍的全局和嵌套函数实际上也是特殊的闭包,闭包采取如下三种形式之一: 1. 全局函数是一个有名字但不会捕获任何值的闭包 2. 嵌套函数是一个有名字并可以捕获其封闭函数域内值的闭包 3. 闭包表达式是一个可以捕获其上下文中变量或常量值的没有名字的闭包 一.闭包表达式 闭包函数类似于Objective-C中的block.下面我们用事实说话: let counts =

swift学习笔记(七)自动引用计数

与Object-c一样,swift使用自动引用计数来跟踪并管理应用使用的内存.当实例不再被使用时,及retainCount=0时,会自动释放是理所占用的内存空间. 注:引用计数仅适用于类的实例,因为struct和enumeration属于值类型,也就不牵涉引用,所以其存储和管理方式并不是引用计数. 当一个实例被初始化时,系统会自动分配一定的内存空间,用于管理属性和方法.当实例对象不再被使用时,其内存空间被收回. swift中的引用类型分为三种,即Strong强引用,weak弱引用和无主引用unw

Swift学习笔记之闭包

简介 (真的很简) 闭包的完整形态是这个样子的: { (parameters) -> returnType in statements } 写在一行里就是这样: {(parameters) -> (returnType) in statements} 形式 闭包以三种形式存在: 1.全局的函数都是闭包,它们有自己的名字,但是没有捕获任何值. 2.内嵌的函数都是闭包,它们有自己的名字,而且从包含他们的函数里捕获值. 3.闭包表达式都是闭包,它们没有自己的名字,通过轻量级的语法定义并且可以从上下文

Swift学习笔记七:集合

数组 Array 数组的创建 OC 中使用 @[] 定义数组, Swift 中使用 [] 定义数组 [类型] 表示数组中存放的都是该类型的元素 Swift 中数组中的元素可以是基本数据类型 // 创建数组 var array1: Array<Int> vararray2:Array<Int> = [2,3] var array3: [Int] var array33 = [Int]() array1 = Array(arrayLiteral: 1, 2, 3, 4) var arr

Swift学习笔记七

控制流 Swift提供了和C类似的控制流表达式,包括for.while.if.switch.当然也包括break和continue这种语句来引导控制流到某个指定点的语句. 在C的for基础上,Swift提供了更强大的for-in,遍历起来更方便. Swift的switch也比C中的更强大,其中的case在执行之后并不会继续执行下一个case,这样就避免了C中忘记写break时产生的逻辑错误.同时,case也能匹配更多的模式,包括间隔匹配,元组等,被匹配的值可以被赋值给变量或者常量,以便在case

swift学习笔记(七)自己主动引用计数

与Object-c一样,swift使用自己主动引用计数来跟踪并管理应用使用的内存.当实例不再被使用时,及retainCount=0时,会自己主动释放是理所占用的内存空间. 注:引用计数仅适用于类的实例,由于struct和enumeration属于值类型,也就不牵涉引用,所以其存储和管理方式并非引用计数. 当一个实例被初始化时,系统会自己主动分配一定的内存空间,用于管理属性和方法.当实例对象不再被使用时,其内存空间被收回. swift中的引用类型分为三种,即Strong强引用,weak弱引用和无主

swift学习笔记(六)析构过程和使用闭包对属性进行默认值赋值

一.通过闭包和函数实现属性的默认值 当某个存储属性的默认值需要定制时,可以通过闭包或全局函数来为其提供定制的默认值. 注:全局函数结构体和枚举使用关键字static标注    函数则使用class关键字标注 当对一个属性使用闭包函数进行赋值时,每当此属性所述的类型被创建实例时,对应的闭包或函数会被调用,而他们的返回值会被作为属性的默认值. ESC: Class SomeCLass{ let someProperty:SomeType={ //给someProperty赋一个默认值 //返回一个与

swift学习笔记(三)关于拷贝和引用

在swift提供的基本数据类型中,包括Int ,Float,Double,String,Enumeration,Structure,Dictionary都属于值拷贝类型. 闭包和函数同属引用类型 捕获则为拷贝.捕获即定义这些常量和变量的原作用域已不存在,闭包仍然可以在闭包函数体内引用和修改这些值 class属于引用类型. Array的情况稍微复杂一些,下面主要对集合类型进行分析: 一.关于Dictionary:无论何时将一个字典实例赋给一个常量,或者传递给一个函数方法时,在赋值或调用发生时,都会

Lua学习笔记(七):迭代器与泛型for

1.迭代器与闭包 迭代器是一种支持指针类型的结构,它可以遍历集合的每一个元素.在Lua中我们常常使用函数来描述迭代器,每次调用该函数就返回集合的下一个元素. 迭代器需要保留上一次成功调用的状态和下一次成功调用的状态,也就是他知道来自于哪里和将要前往哪里.闭包提供的机制可以很容易实现这个任务.记住:闭包是一个内部函数,它可以访问一个或者多个外部函数的外部局部变量.每次闭包的成功调用后这些外部局部变量都保存他们的值(状态).当然如果要创建一个闭包必须要创建其外部局部变量.所以一个典型的闭包的结构包含