美文网首页
每天学一点Swift----闭包(二)

每天学一点Swift----闭包(二)

作者: 冯可乐同学 | 来源:发表于2017-05-21 21:51 被阅读23次

    七.闭包表达式

    1.调用闭包(使用闭包返回值):闭包的本质是功能更加灵活的代码块,因此完全可以将闭包赋值给变量(联想函数类型的变量)或直接调用闭包。举个栗子:

    //定义一个闭包,并为闭包表达式的形参定义外部形参名,然后将闭包赋值给square变量

    var square = {(value val : Int) -> Int in

    return val * val

    }

    //这里和函数赋值给一个变量的实质内容是完全一样的,只是声明的写法不相同而已,对比与函数类型的变量,这里我称为闭包类型的变量

    //使用闭包变量

    println(square(5))//输出25

    println(square(6))//输出36

    //使用闭包表达式来定义闭包,并在闭包表达式后面增加圆括号来调用该闭包

    //----更加牛逼了哈,,这样能调用多次吗??--答案是:no

    var result = {(#base : Int, #exponent : Int) -> Int in

    var result = 1

    for i in exponent

    {

    result *= base

    }

    return result

    }(3, 4)//使用圆括号调用闭包,计算3的4次方,则result得到是闭包的返回值

    println(result)//输出81

    2.从上面的程序中还可以看出,虽然闭包表达式支持为形参指定外部形参名,但这个外部形参名没有任何作用----程序调用闭包时依然不需要外部形参名,因此使用闭包表达式定义闭包是不需要指定外部形参名

    3.完整的闭包表达式需要定义形参类型、返回值类型,但是Swift可以根据闭包表达式上下文推断形参类型、返回值类型,那么闭包表达式就可以省略形参类型、返回值类型。----如果闭包表达式省略了返回值类型,那就无须书写->符号;如果闭包表达式省略了形参类型,则也可以省略形参列表的圆括号。

    4.举个栗子:

    //使用闭包表达式,由于程序定义了square变量的类型,因此Swift可以推断闭包表达式的形参类型、返回值类型,因此可以省略闭包表达式的形参类型、返回值类型

    var square : (Int) -> Int = {(val) in return val * val}

    //省略形参类型后,也可以省略形参列表的圆括号,即上面的代码可以化简如下:

    var square : (Int) -> Int = {val in return val * val}

    println(square(5))// 25

    println(square(6))// 36

    //由于调用闭包表达式传入了4,3,因此Swift可以推断出闭包表达式的两个形参都是Int类型。程序将闭包表达式的返回值赋值给Int类型的变量,因此该闭包表达式的返回值是Int类型,只要Swift可以推断出闭包表达式的形参类型、返回值类型,闭包表达式即可省略形参类型、返回值类型。

    var result : Int = {base, exponent in

    var result = 1

    for i in 1...exponent

    {

    result *= base

    }

    return result

    }(4, 3)

    print(result)// 64

    5.省略return:如果闭包表达式的执行体只有一行代码,而且这行的返回值作为闭包表达式的返回值,那么Swift允许省略return关键字。举个栗子:

    (1)//省略形参类型,省略返回值类型

    //由于该闭包表达式只有一行代码,因此可以省略return关键字

    var square : (Int) -> Int = (val in val * val)

    print(square(5))//输出25

    (2)//由于Swift无法推断闭包表达式的形参类型、返回值类型,因此不能省略形参类型、返回值类型

    //由于闭包表达式只有一行代码,因此可以省略return关键字

    var cube = {(val : Int) -> Int in val * val * val}

    print(cube(5))//输出125

    6.省略形参名:在闭包表达式可以省略形参类型、返回值类型的情况下,Swift甚至允许省略闭包表达式的形参名。如果闭包表达式省略了形参名,in关键字也就不需要了。此时,Swift允许闭包表达式通过$0, $1, $2....名字来引用第一个、第二个、第三个...形参。举个栗子:

    //省略闭包表达式的形参类型、返回值类型、return关键字、形参名

    //$0代表该闭包表达式中唯一的形参

    var square : Int -> Int = {$0 * $0}

    print(square(5))//输出25

    //省略闭包表达式的形参类型、返回值类型、形参名,但不能省略return关键字

    //$0代表该闭包表达式中的第一个形参,$1代表第二个形参

    var result : Int = {

    var result = 1

    for i in 1...$1

    {

    result *= $0

    }

    return result

    }(4, 3)

    print(result)//输出64

    7.尾随闭包

    (1)比如有这样一个函数:func myFunc(val : Int, fn : (Int) -> Int){...}

    因为函数的最后一个参数是函数类型的,所以,程序调用时既可以传入一个函数作为参数,也可以传入一个闭包作为参数,----再次证明,函数类型和闭包类型的实质是相同的。

    (2)如果传入闭包作为参数,那么程序的调用方式为:

    myFunc(20, {doSomethinf...}) ----花括号中的内容是闭包的执行体。

    (3)从上面可以看出,如果传入类闭包作为参数,那么闭包的花括号就在函数的圆括号里面。

    (4)尾随闭包则是一个提高可读性的写法----如果调用函数的***最后一个***参数是闭包,那么Swift将调用函数的圆括号提到闭包表达式的花括号之前,这种用法就被称为尾随闭包。

    myFunc(20){doSomething...}----花括号中的内容是闭包的执行体。

    *****看着跟定义函数的格式很像,用的时候一定要看仔细啊。。。。

    (5)再次举个栗子:

    //定义函数类型的形参,其中fn是(Int) -> Int类型的参数

    func map(var #data : [Int], #fn : (Int) -> Int) -> [Int]

    {

    //遍历data数组中的每个元素,并用fn函数对data[i]进行计算

    //然后将计算结果作为新的数组元素

    for var i=0,len=data.count; i

    {

    data[i] = fn(data[i])

    }

    return data

    }

    var data = {3, 4, 9, 5, 8}

    //调用3次map函数

    //计算数组元素平方。尾随闭包,省略了形参类型、形参名、返回值类型、return关键字

    var result1 = map(data:data){$0, $0}

    //计算数组元素立方。尾随闭包,省略了形参类型、形参名、返回值类型、return关键字

    var result2 = map(data:data){$0, $0, $0}

    //计算数组元素阶乘。尾随闭包,省略了形参类型、形参名、返回值类型,不能省略return关键字

    var result3 = map(data:data){

    var result = 1;

    for index in 2...$0

    {

    result *= index

    }

    return result

    }

    以上就是尾随闭包的用法。

    相关文章

      网友评论

          本文标题:每天学一点Swift----闭包(二)

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