设为首页 加入收藏

TOP

闭包(Closure)(一)
2017-10-09 13:35:04 】 浏览:5188
Tags:闭包 Closure

1.什么是闭包(Closure)?

闭包是一个完整的设计功能模块,可以在代码中传递和使用,类似于Object-C的block(但是还是有区别,下面会说明)或者其他语言的匿名函数(lambdas)。闭包可以捕获或者储存它们所在上下文的常量和变量。在Swift里等价于函数,是一等公民。

闭包有三种形式:

  • 全局函数,有名字的闭包并且不捕获任何值(定义的一般函数)
  • 嵌套函数,有名字的闭包,可以在闭包所在函数内部捕获值(函数里嵌套函数)
  • 闭包表达式,没有名字的闭包,使用简洁的语法,可以在包裹闭包的上下文捕获值(闭包)

举例说明:

 1 //Global function
 2 func block() {
 3     print("block")    //block
 4 }
 5 
 6 //Nested function
 7 func block(){
 8     let name = "block"
 9     func printStr() {
10         print(name)
11     }
12     printStr()
13 }
14 block()    //block
15 
16 //Closure expression
17 let block = {
18     print("block")
19 }
20 block()    //block

 

swift对闭包的表达式做了相关的优化:

  • 从上下文推断传入参数和返回值
  • 单一表表达式闭包的隐式返回
  • 简短的参数名
  • 尾随闭包

举例说明:

let numbers = [1, 3, 2, 4, 7, 8, 5]
let sortedNums = numbers.sorted { (a: Int, b: Int) -> Bool in
    return a > b
}
//下面常量返回的都是[8, 7, 5, 4, 3, 2, 1]

//从上下文推断传入参数和返回值
let sortedNums2 = numbers.sorted { (a, b) in
    return a > b
}

//单一表表达式闭包的隐式返回
let sortedNums = numbers.sorted { $0 > $1 }

//简短的参数名
let sortedNums2 = numbers.sorted { (a, b) in
    return a > b
}

//尾随闭包
let sortedNums = numbers.sorted { $0 > $1 }

 

2.闭包的表达式语法(Closure Expressions)

定义:

{(parameters) -> return type in
  statements
}

 

举一些例子:

//没有参数和返回值的block定义
let noParameterAndNoReturnValue: () -> () = {
    print("Hello world!")
}

//没有参数,有返回值的block定义
let noParameterAndReturnValue: () -> (Int) = {
    return 5
}

//有一个参数和返回值的block定义
let oneParameterAndNoReturnValue: (Int) -> (Int) = { x in
    return x + 2
}

//有多个参数和返回值的block定义
let mutipleParameterAndNoReturnValue: (Int, Int) -> (Int) = { (x, y) in
    return x + y
}

 

3.简短的参数名字(Shorthand argument syntax)
 1 // swift支持类型推断,什么意思呢?就是闭包的参数和返回类型都可以交给编译器去推断,在编码阶段就可以省略。闭包里面$0,$1代表的是传入的第一个参数和第二个参数,下面看代码:
 2 
 3 //$0代表第一个参数,$1代表第二个参数,语法非常简洁
 4 let numbers = [1, 3, 2, 4, 7, 8, 5]
 5 let sortedNums = numbers.sorted { $0 > $1 }    //[8, 7, 5, 4, 3, 2, 1]
 6 // 顺便提一下函数(闭包)参数省略的过程,还是以数组降序为例:
 7 
 8 let numbers = [1, 3, 2, 4, 7, 8, 5]
 9 let sortedNums = numbers.sorted { (a: Int, b: Int) -> Bool in
10     return a > b
11 }    //[8, 7, 5, 4, 3, 2, 1]
12 // 如果一个函数的返回类型和参数类型可以推导出来,则返回类型和参数类型都可以省略。删除:Int,-> Bool,上面的表达式变成:
13 
14 let numbers = [1, 3, 2, 4, 7, 8, 5]
15 let sortedNums = numbers.sorted { (a, b) in
16     return a > b
17 }    //[8, 7, 5, 4, 3, 2, 1]
18 // 如果参数的个数可以推导出来,则参数可以省略,使用$0,$1的方式代表参数。参数省略了,in关键字在这里就没有意义了,也可以省略,则上面的表达式变成:
19 
20 let numbers = [1, 3, 2, 4, 7, 8, 5]
21 let sortedNums = numbers.sorted {
22     return $0 > $1
23 }    //[8, 7, 5, 4, 3, 2, 1]
24 // 在swift里,如果函数体只有一行,则可以把return关键字省略,单一表达式闭包隐式返回,则代码进一步演变成:
25 
26 let numbers = [1, 3, 2, 4, 7, 8, 5]
27 let sortedNums = numbers.sorted {
28    $0 > $1
29 }    //[8, 7, 5, 4, 3, 2, 1]
30 // 最后,还能更近一步简化。可能很多人都郁闷了,就剩两个参数和操作符了,还能怎么简化?别急,swift里面还有一个简化规则,因为<也是函数,并且和函数sorted函数接收的参数个数,类型和返回值都一样,所以,能推导出来的东西都能简化,那么,更暴力的简化来了:
31 
32 let numbers = [1, 3, 2, 4, 7, 8, 5]
33 let sortedNums = numbers.sorted (by: > )    //[8, 7, 5, 4, 3, 2, 1]
34 // 看出来什么了没有?没错,这里的简化不是放在闭包里面的。我的理解是,整个闭包等价于>函数,所以,可以把整个闭包替换成了>函数,举个例子:
35 
36 let block: (Int, Int) -> (Int) = { $0 + $1 }
37 func testBlock(block: (Int, Int) -> (Int)) -> Int {
38     return block(1,3)
39 }
40 
41 testBlock{ $0 + $1 }    //3
42 testBlock(block: block)    //3

 

4.尾随闭包(Trailing Closures)

If you need to pass a closure expression to a function as the function’s final argument and the closure expression is long, it can be useful to write

首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Swift的Guard语句 下一篇Swift语言中与C/C++和Java不同的..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目