美文网首页
24 闭包和闭包表达式

24 闭包和闭包表达式

作者: 为了自由的白菜 | 来源:发表于2023-03-13 17:22 被阅读0次

闭包和闭包表达式

闭包的概念

  • 闭包是可以在你的代码中被传递和引用的功能性独立代码块

  • 闭包能够捕获和存储定义在其上下文中的任何常量和变量的引用,这也就是所谓的闭包并包裹那些常量和变量,因为被称为“闭包”,Swift能够为你处理所有关于捕获的内存管理的操作

  • 在函数章节中有介绍的全局和内嵌函数,实际上是特殊的闭包。闭包符合如下三种形式中的一种:

    1. 全局函数是一个有名字但不会捕获任何值的闭包
    2. 内嵌函数是一个有名字且能从其上层函数捕获值得闭包
    3. 闭包表达式是一个轻量级语法所写的可以捕获其上下文中常量或变量值得没有名字的闭包

闭包表达式

  • 闭包表达式是一种在简短行内就能写完闭包的语法

闭包表达式-从sorted函数说起

  • Swift的标准库提供了一个叫做sorted(by:)的方法,会根据你提供的排序闭包将已知类型的数组的值进行排序。一旦它排序完成,sorted(by:)方法会返回与原数组类型大小完全相同的一个新数组,该数组的元素是已排序好的。原始数组不会被sorted(by:)方法修改
image-20230226214726609.png

闭包表达式语法

  • 闭包表达式语法能够使用常量形式参数、变量形式参数和输入输出形式参数,但不能提供默认值。可变形式参数也能使用,但需要在形式参数列表的最后面使用。元组也可被用来作为形式参数和返回类型
image-20230226215028999.png

闭包表达式语法版本的backward

  • 将之前backward(_:_:)函数改为闭包表达式版本
image-20230226215214643.png

从语境中推断类型

  • 因排序闭包为实际参数来传递给函数,故Swift能推断它的形式参数类型和返回类型
  • sorted(by:)方法期望它的形式参数是一个(String, String) -> Bool类型的函数。这意味着(String, String)和Bool类型不需要被写成闭包表达式定义中的一部分,因为所有类型都能被推断,返回箭头(->)和围绕在形式参数名周围的括号也能被省略
image-20230226220555466.png

从单表达式闭包隐式返回

  • 单表达式闭包能够通过从它们的声明中删掉return关键字来隐式返回它们单个表达式的结果
image-20230226220807098.png

简写实际参数名

  • Swift自动对行内闭包提供简写实际参数名,可以通过0,1, $2等名字来引用闭包的实际参数值
image-20230226220949657.png

运算符函数

  • Swift的String类型定义了关于大于号(>)的特定字符串实现,让其作为一个有两个String类型形式参数的函数并返回一个Bool类型的值。这正好与sorted(by:)方法的形式参数需要的函数相匹配。因为,你能简单地传递一个大于号,并且Swift将推断你想使用大于号特殊字符串函数实现
image-20230226221254597.png

尾随闭包

  • 如果你需要将一个很长的闭包表达式作为函数最后一个实际参数传递给函数,使用尾随闭包将增强函数的可读性。尾随闭包是一个被书写在函数形式参数的括号外面(后面)的闭包表达式
image-20230226221503838.png

闭包如何捕获值

捕获值

  • 一个闭包能够从上下文捕获已被定义的常量和变量。即使定义这些常量和变量的原作用域已经不存在,闭包仍能够在其函数体内引用和修改这些值
image-20230226223314922.png
  • 作为一种优化,如果一个值没有改变或者在闭包的外面,Swift可能会使用这个值得拷贝而不是捕获
  • Swift也处理了变量的内存管理操作,当变量不再需要时会被释放
image-20230226223618291.png
  • 如果你建立了第二个incrementer,它将会有一个新的、独立runningTotal变量的引用
image-20230226223756484.png

闭包是引用类型

  • 在Swift中,函数和闭包都是引用类型
  • 无论你什么时候赋值一个函数或者闭包给常量或者变量,你实际上都是将常量和变量设置为对函数和闭包的引用
image-20230226223947872.png
  • 如果你分配了一个闭包给类实例的属性,并且闭包通过引用该实例或者它的成员来捕获实例,你将在闭包和实例间会产生循环引用

逃逸闭包和自动闭包

逃逸闭包

  • 当闭包作为一个实际参数传递给一个函数的时候,并且它会在函数返回之后调用,我们就说这个闭包逃逸了。当你声明一个接受闭包作为形式参数的函数时,你可以在形式参数前写@escaping来明确闭包是允许逃逸的
  • 闭包可以逃逸的一种方法是被储存在定义与函数外的变量里。比如说,很多函数接受闭包实际参数来作为启动异步任务的回调。函数在启动任务后返回,但是闭包要直到任务完成--闭包需要逃逸,以便于稍后调用
image-20230226225428250.png
  • 让闭包@escaping意味着你必须在闭包中显式地引用self
image-20230226225625375.png

自动闭包

  • 自动闭包是一种自动创建的用来把作为实际参数传递给函数的表达式打包的闭包。它不接收任何实际参数,并且当它被调用时,它会返回内部打包的表达式的值
  • 这个语法的好处在于通过写普通表达式代替显示闭包而使你省略包围函数形式参数的括号
image-20230226225935693.png
  • 自动闭包允许你延迟处理,因为闭包内部的代码直到你调用它的时候才会运行。对于有副作用或者占用资源的代码来说很有用,因为它可以允许你控制代码何时才进行求值
image-20230226230232024.png
  • 当你传一个闭包作为实际参数到函数的时候,你会得到与延迟处理相同的行为
image-20230226230707680.png
  • 通过@autoclosure标志标记它的形式参数使用了自动闭包。现在你可以调用函数就像它接受了一个String实际参数而不是闭包。实际参数自动地转换为闭包,因为customerProvider形式参数的类型被标记为@autoclosure标记
image-20230226230946051.png

自动+逃逸

  • 如果你想要自动闭包允许逃逸,就同时使用@autoclosure和@escaping标志
image-20230227202524432.png

相关文章

  • Day7 闭包(Closures)

    本页包含内容:• 闭包表达式• 尾随闭包• 值捕获• 闭包是引用类型• 逃逸闭包• 自动闭包 1、闭包表达式 闭包...

  • Swift基础语法-闭包,闭包函数回调,尾随闭包,闭包捕获值,循

    本节知识点 闭包的基本概念 闭包基本使用 闭包表达式作为回调函数 闭包的多种写法(尾随闭包) 闭包表达式优化 闭包...

  • swift- 闭包一

    /*• 闭包表达式• 尾随闭包• 值捕获• 闭包是引用类型• 逃逸闭包• 自动闭包*/

  • 闭包

    闭包 本节内容包括: 闭包表达式 尾随闭包 值捕获 闭包是引用类型 Swift 中的闭包与 C 和 Objecti...

  • Swift~ @escaping @noescaping 逃逸

    闭包表达式语法 闭包表达式语法有如下的一般形式: 闭包只有在函数中做参数时,才会区分逃逸闭包和非逃逸闭包 Swif...

  • 07-闭包

    闭包表达式(Closure Expression) 闭包表达式的简写 尾随闭包 示例 - 数组的排序 忽略参数 闭...

  • Swift 闭包

    闭包 闭包是保存一段代码块,可以在代码中传递和是使用(类似Block) 闭包和block类似 闭包的表达式如下闭包...

  • 12 闭包

    要说明的是,【闭包】和【闭包表达式】不是一回事,你可将【闭包表达式】看作是【闭包】的一种形式。因为闭包还有其他两种...

  • swift 闭包与闭包表达式

    闭包与闭包表达式 在swift里闭包大家都很熟悉,相当于oc中的block。闭包表达式又是啥?很多人把闭包表达式等...

  • 闭包 Closure

    内容摘要: 闭包介绍 闭包表达式 尾随闭包 值捕获 逃逸闭包 自动闭包 一、闭包介绍 闭包是自包含的函数代码块,可...

网友评论

      本文标题:24 闭包和闭包表达式

      本文链接:https://www.haomeiwen.com/subject/pwbcrdtx.html