美文网首页
11、Swift 中的闭包

11、Swift 中的闭包

作者: Fred丶Lee | 来源:发表于2023-04-25 11:42 被阅读0次

    在 Swift 中,闭包是一种引用类型,类似于函数,可以捕获和存储上下文中的值。闭包在 Swift 中非常常见,可以用于简化代码,提高性能和可读性。本文将介绍闭包的基本语法和用法,并提供一些示例代码,以帮助您更好地理解闭包。

    闭包的基本语法

    闭包的基本语法如下:

    { (parameters) -> return type in
        statements
    }
    

    其中,parameters 指定闭包的参数列表,可以为空;return type 指定闭包的返回类型,可以省略;in 关键字分隔参数列表和代码块;statements 是闭包的代码块,用于执行操作并返回结果。

    例如,以下是一个简单的闭包,用于计算两个整数的和:

    let add: (Int, Int) -> Int = { (a, b) in
        return a + b
    }
    

    这个闭包接受两个整数作为参数,并返回它们的和。可以使用以下方式调用它:

    let result = add(3, 5)
    print(result) // 输出 8
    

    尾随闭包

    尾随闭包是一种特殊的闭包语法,可以让代码更加简洁。它将闭包的代码块放在函数调用的括号外面,并在函数调用的括号后面使用一对花括号括起来。例如:

    let numbers = [1, 2, 3, 4, 5]
    let mapped = numbers.map { $0 * 2 }
    

    在这个例子中,map 方法接受一个闭包作为参数,并对数组中的每个元素执行操作。尾随闭包使代码更加简洁,也更容易阅读。

    自动闭包

    自动闭包是一种特殊的闭包语法,可以延迟计算。它将表达式封装在一个闭包中,并在需要的时候才执行。例如:

    func printIfTrue(_ predicate: () -> Bool) {
        if predicate() {
            print("条件为真")
        }
    }
    
    printIfTrue({ 2 > 1 })
    

    在这个例子中,printIfTrue 函数接受一个返回布尔值的闭包作为参数。可以使用自动闭包来简化代码:

    func printIfTrue(_ predicate: @autoclosure () -> Bool) {
        if predicate() {
            print("条件为真")
        }
    }
    
    printIfTrue(2 > 1)
    

    使用自动闭包时,可以直接传递一个表达式,而不需要显式地创建一个闭包。

    闭包的捕获

    闭包可以捕获和存储上下文中的值。在 Swift 中,有两种方式可以捕获值:引用捕获和值捕获。

    引用捕获会捕获变量或常量的引用,并在闭包中使用该引用。这意味着,如果原始变量或常量发生更改,闭包中捕获的值也会随之更改。例如:

    func makeIncrementer(forIncrement amount: Int) -> () -> Int {
        var runningTotal = 0
        func incrementer() -> Int {
            runningTotal += amount
            return runningTotal
        }
        return incrementer
    }
    
    let incrementByTen = makeIncrementer(forIncrement: 10)
    print(incrementByTen()) // 输出 10
    print(incrementByTen()) // 输出 20
    

    在这个例子中,makeIncrementer 函数返回一个闭包,该闭包每次调用时会增加一个固定的量,并返回递增后的值。闭包捕获了 runningTotal 变量的引用,因此该变量的值在多次调用闭包时保持不变。

    值捕获会在闭包内部创建变量或常量的副本,并在闭包中使用这些副本。这意味着,如果原始变量或常量发生更改,闭包中捕获的值不会受到影响。例如:

    func makeIncrementer(forIncrement amount: Int) -> () -> Int {
        var runningTotal = 0
        let incrementer = { [amount] () -> Int in
            runningTotal += amount
            return runningTotal
        }
        return incrementer
    }
    
    let incrementByTen = makeIncrementer(forIncrement: 10)
    print(incrementByTen()) // 输出 10
    print(incrementByTen()) // 输出 20
    

    在这个例子中,闭包捕获了 amount 常量的值,而不是捕获 runningTotal 变量的引用。因此,runningTotal 的值在多次调用闭包时发生更改,但 amount 的值保持不变。

    示例代码

    以下是一些示例代码,演示了闭包的不同用法:

    // 定义一个接受两个整数并返回它们的和的闭包
    let add: (Int, Int) -> Int = { (a, b) in
        return a + b
    }
    print(add(3, 5)) // 输出 8
    
    // 使用尾随闭包对数组中的每个元素进行平方处理
    let numbers = [1, 2, 3, 4, 5]
    let squared = numbers.map { $0 * $0 }
    print(squared) // 输出 [1, 4, 9, 16, 25]
    
    // 使用自动闭包判断两个整数是否相等
    func isEqual(_ a: Int, _ b: Int, _ predicate: @autoclosure () -> Bool) {
        if predicate() {
            print("\(a) 等于 \(b)")
        } else {
            print("\(a) 不等于 \(b)")
        }
    }
    isEqual(2, 2, 2 == 2) // 输出 "2 等于 2"
    isEqual(2, 3, 2 == 3) // 输出 "2 不等于 3"
    
    // 使用引用捕
    //获取外部变量的值
    func makeCounter() -> () -> Int {
    var count = 0
    let counter = { () -> Int in
    count += 1
    return count
    }
    return counter
    }
    
    let counter = makeCounter()
    print(counter()) // 输出 1
    print(counter()) // 输出 2
    
    // 使用值捕获避免捕获引用
    func makeArray() -> [() -> Int] {
    var array: [() -> Int] = []
    for i in 1...5 {
    array.append { [i] () -> Int in
    return i
    }
    }
    return array
    }
    
    let array = makeArray()
    for function in array {
    print(function()) // 输出 1, 2, 3, 4, 5
    }
    
    // 使用逃逸闭包进行异步处理
    func fetchData(completionHandler: @escaping (String) -> Void) {
    DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
    let data = "Hello, world!"
    completionHandler(data)
    }
    }
    
    fetchData { (data) in
    print(data) // 输出 "Hello, world!"
    }
    

    以上是一些 Swift 中使用闭包的示例,这些示例展示了闭包在不同情况下的灵活性和实用性。闭包是 Swift 中一个重要的特性,对于开发高效和可维护的代码非常有帮助。在开发 Swift 应用程序时,了解和熟练掌握闭包的使用是非常重要的。

    相关文章

      网友评论

          本文标题:11、Swift 中的闭包

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