Swift闭包的三种形式以及理解闭包的嵌套函数
Swift闭包的三种形式以及理解闭包的嵌套函数

Swift闭包的三种形式以及理解闭包的嵌套函数

闭包的定义

闭包(Closure) 是一种能够捕获和存储其所在上下文中的变量和常量的独立代码块。换句话说,闭包可以在定义时捕获其作用域内的变量,并在闭包的生命周期内使用和修改这些变量。

闭包在 Swift 中的表现有点像匿名函数,但更强大。它们可以作为参数传递,也可以作为返回值返回,还可以持有并修改其作用域内的变量,即使作用域已经销毁,闭包仍然可以访问这些变量。

闭包的三种形式

在 Swift 中,闭包有三种主要的形式:

1、全局函数:有名字并且不会捕获任何值的闭包。

    全局函数是定义在全局范围内的函数,它们有名字,并且不会捕获任何值。这些函数可以在代码的任何地方使用,因为它们存在于全局作用域中。

    func greet(name: String) -> String {
        return "Hello, \(name)!"
    }

    这里的 greet 就是一个全局函数。它不会捕获任何外部变量,因为它定义在全局范围内。

    上面的全局函数在语法上是普通的命名函数,但实际上,也属于闭包的一种形式。

    广义上来讲,闭包是一个功能块,可以被传递和使用。根据Swift文档的定义,闭包是一个可以捕获和存储外部作用域中的变量的字包含代码块。

    2、嵌套函数:有名字并且可以捕获其上层函数中的值。

      嵌套函数是定义在另一个函数内部的函数。它们可以捕获并存储外层函数中的变量。这使得嵌套函数在保持状态信息或创建一些专用的逻辑时非常有用。

      func makeMultiplier(by multiplier: Int) -> (Int) -> Int {
          func multiplierFunction(number: Int) -> Int {
              return number * multiplier
          }
          return multiplierFunction
      }
      
      let multiplyByTwo = makeMultiplier(by: 2)
      print(multiplyByTwo(3))  // 输出: 6

      在这个例子中,multiplierFunction 是 makeMultiplier(by:) 的嵌套函数。由于 multiplierFunction 是在 makeMultiplier 内部定义的,它可以捕获 multiplier 的值并在执行时使用它。

      3、闭包表达式:没有名字的闭包,可以捕获其上下文中的值。

        闭包表达式是一段没有名字的代码块,可以捕获其所在上下文中的变量。它们是一种更灵活的匿名函数,可以用简洁的语法进行定义。闭包表达式非常适合用于需要传递函数作为参数的场景。

        let add: (Int, Int) -> Int = { (a, b) in
            return a + b
        }
        print(add(3, 4))  // 输出: 7

        在这个例子中,add 是一个变量,类型是 (Int, Int) -> Int,表示一个接受两个 Int 参数并返回一个 Int 值的闭包。

        { (a, b) in return a + b } 是一个匿名闭包,可以直接赋值给 add 变量。

        (a, b) 是闭包的参数列表,-> Int 表示闭包的返回类型,in 之后是闭包的代码体。

        为什么看起来像赋值?

        因为 Swift 中,闭包本质上也是一种数据类型,所以可以像赋值其他数据类型(如 Int、String)一样进行赋值。

        定义了闭包类型的变量后,你就可以把符合这个类型的闭包赋值给它。

        变量后面为什么可以跟两个参数

        这就是闭包的方便之处。由于 add 被赋值为一个接受两个参数的闭包,所以当你调用 add(3, 4) 时,它就像调用一个普通的函数一样,执行闭包里的代码。

        在本例中,调用 add(3, 4) 相当于执行 { (a, b) in return a + b },其中 a = 3,b = 4,结果返回 7。

        闭包的语法

        闭包表达式的语法一般如下:

        { (参数列表) -> 返回类型 in
            // 闭包的代码
        }

        参数列表:和函数参数类似,用来传递输入值给闭包。

        返回类型:定义了闭包返回的值。

        in:分隔了参数和闭包体。

        闭包的特点

        捕获环境变量:闭包可以捕获其定义时的上下文变量(外部变量),并且在闭包的生命周期内这些变量都可以被访问和修改。

        延迟执行:闭包不会在定义时执行,而是在你明确调用时执行。你可以将闭包作为参数传递给函数或者存储在变量中,随时调用。

        可以作为返回值:闭包可以从一个函数中返回,并且可以在其他地方使用。

        理解闭包的嵌套函数

        代码分析

        前面涉及闭包的嵌套函数部分,在这里进一步进行解析:

        func makeMultiplier(by multiplier: Int) -> (Int) -> Int {
            func multiplierFunction(number: Int) -> Int {
                return number * multiplier
            }
            return multiplierFunction
        }
        函数makeMultiplier(by:)

        首先是一个makeMultiplier(by:)函数,它接受一个整数multiplier作为参数,返回值的类型是(Int) -> Int,表示返回的函数会接受一个Int并且返回一个Int。

        嵌套函数multiplierFunction(number:)

        里面是嵌套函数multiplierFunction(number:),它接受一个参数number,并且返回number * multiplier。

        返回值

        最后,makeMultiplier(by:) 返回的是 multiplierFunction,这是一个可以使用 multiplier 参数的函数。

        使用过程

        let multiplyByTwo = makeMultiplier(by: 2)
        print(multiplyByTwo(3))  // 输出: 6
        makeMultiplier(by: 2) 调用

        当调用 makeMultiplier(by: 2) 时,multiplier 被设置为 2。

        它返回一个嵌套函数 multiplierFunction,这个函数会将 multiplier 捕获。

        现在,multiplyByTwo 变量保存了 multiplierFunction,并且记住了 multiplier 的值 2。

        multiplyByTwo(3) 调用

        调用 multiplyByTwo(3) 相当于调用 multiplierFunction(number: 3)。

        multiplierFunction 使用了捕获的 multiplier 值(2),计算 3 * 2,最终结果为 6。

        嵌套函数的特点:嵌套函数可以访问外部函数的参数和变量。在 makeMultiplier(by:) 中,multiplierFunction 就能使用外部的 multiplier 参数,这样的机制称为“捕获”。

        返回函数:makeMultiplier(by:) 返回了 multiplierFunction,这个函数在调用时仍然“记得”它的 multiplier 参数。

        闭包的常见用途

        回调函数:在异步操作中,当操作完成时执行某个代码块。

        事件处理器:处理按钮点击、手势等用户操作。

        作为参数传递和返回:提高代码的灵活性和可复用性。

        内存管理:捕获外部变量来维持状态信息。

        总结来说,闭包是一种灵活且强大的代码块,允许你将代码的逻辑和状态保持在一起,方便传递和操作。这使得 Swift 开发中的异步操作、回调和数据处理变得更加自然和高效。

        如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开放者。

        发表回复

        您的电子邮箱地址不会被公开。 必填项已用 * 标注