美文网首页
Swift - 闭包

Swift - 闭包

作者: 汪小喵 | 来源:发表于2016-12-29 17:05 被阅读14次

    前面介绍的全局函数和嵌套函数,就是特殊的闭包。闭包是一个功能性自包含模块,可以在代码中被当作参数传递或者直接使用,类似于Objective-C中的block或其他语言中的匿名函数。
    我们使用一对花括号“{}”来表示闭合并包裹着一段程序代码,由这对花括号包裹的这段代码块就是一个闭包。
    (1)闭包的定义
    闭包的语法形式:

    {
        (参数名1:参数类型,参数名2:参数类型...) ->返回值类型  in
        闭包函数体
        return  返回值
    }
    

    in 关键字表示闭包的参数和返回值类型定义已经完成,参数和返回值将在下面的函数体中得到处理。下面是一段示例代码:

    let sumFunc = {
        (x: Int, y : Int) -> Int
        in
        return x + y
    }
    print(sumFunc(10,20))
    

    需要注意的是,与调用函数不同,在调用闭包时,闭包参数并不会出现外部参数名。
    如果一个闭包没有参数和返回值,in都可以省略掉,那么就成了一个最简单的闭包:

    let simpleFunc = {
        print("这是最简单的闭包")
    }
    

    (2)尾随闭包
    尾随闭包是一个书写在函数括号之后的闭包表达式,先来看一段代码:

    func calculate(opr:String, funN:(Int,Int)->Int) {
        switch opr {
        case "+":
            print("10 + 5 = \(funN(10, 5))")
        default:
            print("10 - 5 = \(funN(10, 5))")
        }
    }
    
    calculate("+", funN:{(a:Int,b:Int)->Int in return a + b})
    calculate("-"){(a:Int,b:Int)->Int in return a - b}
    
    尾随闭包

    在调用函数的过程中可以看到,函数的参数很长,所以可以将小括号提前到大括号之前,这样可以增强代码的可读性。
    注意:尾随闭包必须是参数列表的最后一个参数

    (3)使用闭包表达式
    Swift中闭包的表达式非常灵活,针对不同的情况,提供了多种闭包的简化写法:
    根据上下文推断类型
    我们先看一个标准的闭包:

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

    Swift可以推断出参数a和b都是Int类型,,返回值也是Int类型,上面的代码可以简化成一行:

    {a,b in return a + b}
    

    下面就使用这种简化形式,编写一个示例:

    func calculate(opr : String) -> (Int, Int) -> Int {
        var result : (Int, Int) -> Int
        switch opr {
        case "+":
            result = {a, b in return a + b}
        default:
            result = {a, b in return a - b}
        }
        return result
    }
    
    let f1:(Int, Int) -> Int = calculate("+")
    print("10 + 5 = \(f1(10, 5))")
    let f2:(Int, Int) -> Int = calculate("-")
    print("10 - 5 = \(f2(10, 5))")
    

    "result = {a, b in return a + b}"这行代码就是闭包的简化形式。

    单行闭包表达式可以省略return关键字
    如果在闭包内部的语句组只有一条语句,这条语句就是返回语句,此时,前面的return也可以省略。还是刚刚提到的例子,省略之后的代码如下:

    func calculate(opr : String) -> (Int, Int) -> Int {
        var result : (Int, Int) -> Int
        switch opr {
        case "+":
            result = {a, b in a + b}
        default:
            result = {a, b in a - b}
        }
        return result
    }
    

    参数名称缩写
    虽然根据前面所提到的,闭包已经很简洁了,但是我们还可以继续进行简化。这就用到了参数所写功能,用$0代表第一个参数,$1代表第二个参数,以此类推,$n代表第n+1个参数。我们用这种方式继续简化上面的代码:

    func calculate(opr : String) -> (Int, Int) -> Int {
        var result : (Int, Int) -> Int
        switch opr {
        case "+":
            result = {$0 + $1}
        default:
            result = {$0 - $1}
        }
        return result
    }
    
    let f1:(Int, Int) -> Int = calculate("+")
    print("10 + 5 = \(f1(10, 5))")
    let f2:(Int, Int) -> Int = calculate("-")
    print("10 - 5 = \(f2(10, 5))")
    

    使用闭包返回值
    闭包实质上是函数类型,是有返回值的,所以可以在表达式中使用闭包的返回值:

    let c : Int = {
        (a : Int, b : Int) -> Int in
        return a + b
    } (10,5)
    print(c)
    

    上面的代码就是给常量c赋值,等号后面是一个闭包表达式,但是由于c是Int类型,闭包表达式不能直接赋值给Int类型的c,这就需要闭包的返回值。在闭包的末尾,花括号后面跟上一对小括号,给闭包传递参数,就实现了赋值。

    相关文章

      网友评论

          本文标题:Swift - 闭包

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