美文网首页
每天学一点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----闭包(二)

    七.闭包表达式 1.调用闭包(使用闭包返回值):闭包的本质是功能更加灵活的代码块,因此完全可以将闭包赋值给变量(联...

  • 每天学一点Swift----闭包(三)

    八.捕获上下文中的变量和常量 1.闭包可以用访问或修改闭包所在上下文中的变量或常量(对于常量只是访问),这个过程被...

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

    五.嵌套函数 1. Swift还支持在函数体内定义函数,这种在函数体内定义的函数称为嵌套函数 2.默认情况下,嵌套...

  • Swift----闭包

    闭包是自包含的函数代码块,可以在代码中被传递和使用. 闭包可以捕获和存储其所在上下文中任意常量和变量的引...

  • 每天学一点Swift----集合(二)

    三.字典:字典中以key-value的形式保存数据,所以同一个字典中key不能重复。 1.声明字典--两种方式 (...

  • 每天学一点Swift----函数(二)

    三.函数类型 1. Swift的每个函数都有类型的,函数类型由函数的形参列表,返回值类型组成。 2.使用函数类型定...

  • 每天学一点Swift----泛型(二)

    四.类型约束 1.虽然程序可以对泛型形参传入任何类型,但有时候为泛型形参增加某种特定的约束也是必要的。就像字典,D...

  • 每天学一点Swift----面向对象上(二)

    三.类和结构体 1. Swift的类和结构体高度相似,无论在定义语法上还是在用法上。 2.结构体和类的主要区别是:...

  • 每天学一点Swift----面向对象下(二)

    二.类的构造和析构 1.通过集成后,子类中不仅有父类中的存储属性,还有子类自己的存储属性。子类中的所有存储属性都必...

  • 每天学一点Swift----函数(一)

    1. Swift中支持嵌套函数。 2.与函数紧密相关的另一个概念是闭包,闭包的本质是匿名函数,闭包可以作为表达式,...

网友评论

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

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