《swift 从入门到精通 》~ 基础篇(闭包)
参考:
《swift 从入门到精通 》~ 基础篇(数据类型 )https://blog.csdn.net/shihuboke/article/details/109553998
《swift 从入门到精通 》~ 基础篇(运算符、字符串 )https://blog.csdn.net/shihuboke/article/details/110203341
《swift 从入门到精通 》~ 基础篇(控制流、函数)https://blog.csdn.net/shihuboke/article/details/112144958
《swift 从入门到精通 》~ 基础篇(集合、数组、字典)https://blog.csdn.net/shihuboke/article/details/110672581
一、闭包
1、闭包表达式
闭包是一种功能性自包含模块,可以捕获和存储上下文中任意常量和变量的引用
闭包有三种 形式,分别如下
第一种全局函数 : 有名字但不会捕获任何值得闭包
第二种嵌套函数 : 有名字并可以捕获其封闭函域内值得闭包
第三种闭包表达式: 没有名字但可以捕获上下文中变量和常量的闭包
注意: 全局函数和嵌套函数是特殊形式的闭包
2、闭包的定义
所谓闭包就是将其变量和常量封装在自己的作用域内。闭包可以访问、存储和操作上下文中的任何比 那里和常量,这个过程称为变量或者常量被闭包捕获
//闭包的定义
{ (parameters) ->returnTypein
statements
}
// 闭包表达式可以是常量和变量,也可以用inout 类型,但不能提供默认值
// 参数列表中最后一个参数可以是可变参数,也可以用元组作为参数和返回值
// 闭包中元素都在花括号里,并用关键字 in 连接
例子:
vartheClosure = { (s1:String, s2:String) ->Boolin
returns1 > s2
}
3、闭包类型参数
全局函数做闭包类型参数例子:
letcityArray = ["beijing","shanghai","guangzhou","hanghzou"]
4、闭包类型参数
// 闭包类型参数
funcexchange(s1:String, s2:String)->Bool{
returns1 > s2
}
// 闭包类型参数
letdescendingArray = cityArray.sorted(by: exchange)
print(descendingArray)
// 打印结果 ["shanghai", "hanghzou", "guangzhou", "beijing"]
把exchange()函数改写为闭包,作为参数
letdescengdingArrayByClosures = cityArray.sorted(by: {(s1:String,s2:String) ->Boolin
returns1 > s2 })
print(descengdingArrayByClosures)// 打印结果 ["shanghai", "hanghzou", "guangzhou", "beijing"]
5、闭包表达式的简化
// swift 提供一种参数简写的方法即$0表示第一个参数,$1表示第二个参数,采取这种参数的方法连参数声明都多余的
// { s1 > s2 } 可以简写为 {$0 > $1 }, 也可简化为 { > }
//闭包表达式的简化
letdescendingArray2 = cityArray.sorted(by: {s1,s2inreturns1 > s2})
letdescendingArray3 = cityArray.sorted(by: {s1,s2ins1 > s2})
letdescendingArray4 = cityArray.sorted(by: {$0> $1})
letdescendingArray5 = cityArray.sorted(by: > )
print("descendingArray2 == \(descendingArray2) \ndescendingArray3== \(descendingArray3) \ndescendingArray4 == \(descendingArray4) \ndescendingArray5 == \(descendingArray5)")
// 打印结果
descendingArray2 == ["shanghai","hanghzou","guangzhou","beijing"]
descendingArray3== ["shanghai","hanghzou","guangzhou","beijing"]
descendingArray4 == ["shanghai","hanghzou","guangzhou","beijing"]
descendingArray5 == ["shanghai","hanghzou","guangzhou","beijing"]
//注意: 越简化可能会降低可读性
6、无参数无返回值得闭包
当闭包的类型为()->Void时,称之为无参数无返回值闭包,一对空括号表示没有参数,但是不能省略,
Void表示无返回值,也不能省略,否则编译器无法断定其为闭包
分为显示声明和隐式声明二种 - 例子:
// 显示声明
letviodClosureWithTypeDeclaration : () ->Void= {
print("====显示声明")
}
// 隐式声明
letvoidClosure = {
print("====隐式声明")
}
viodClosureWithTypeDeclaration()
voidClosure()
打印结果:
====显示声明
====隐式声明
7、尾随闭包
如果闭包表达式是函数的最后一个参数,则可以使用尾随闭包的方式增加代码的可读性
尾随闭包是将整个闭包表达式从函数的参数括号里移到括号外面的一种书写方式
调用函数时有二种写法:
一种:将整个闭包作为参数的写法
二种: 尾随闭包的写法,但是采用第二种尾随闭包的写法会明显提升可读性
例子:
funcmathCompute(opr:String,n1:Int, n2: Int, compute:(Int,Int)->Int) {
switchopr {
case"+":
print("\(n1)+\(n2) = \(compute(n1,n2))")
case"-":
print("\(n1)-\(n2) = \(compute(n1,n2))")
case"*":
print("\(n1)*\(n2) = \(compute(n1,n2))")
case"/":
print("\(n1)/\(n2) = \(compute(n1,n2))")
default:print("not support this operator")
}
}
// 调用:
mathCompute(opr:"*", n1:9, n2:3) { (n1, n2) ->Intin
n1*n2
}
// 打印结果: 9*3 = 27
补充:Swift5之后统一了
8、闭包的应用
捕获闭包作用域的变量
// let minusNumber:()->Void = { } 简写为 let minusNumber = { }
// let minusNumber:()->Int = { }
方法 forEach()
方法 forEach()
集合类型汇总的方法 forEach()负责遍历集合中的每一个元素,而对元素的操作可以通过闭包给出.
例子:
varnumber = [1,2,3,4,5,6]
number.forEach { (numberS)in
print("numberS===\(numberS)")
}
number.forEach {
print("numberS== $0 ==\($0) = is")
}
// 理解: 如果不要参数 (numberS) in ,就用$0 代替 numberS
/**
// 打印结果:
numberS===1
numberS===2
numberS===3
numberS===4
numberS===5
numberS===6
numberS== $0 ==1 = is
numberS== $0 ==2 = is
numberS== $0 ==3 = is
numberS== $0 ==4 = is
numberS== $0 ==5 = is
numberS== $0 ==6 = is
*/
方法 filter()
方法filter()
方法filter()负责按照一定的条件将集合中元素过滤出来,并形成一个新的集合,过滤的条件由闭包类型的参数提供
letfilteredNumbers = number.filter{ (numbers) ->Boolin
returnnumbers >3
}
letfilteredNumbersD = number.filter{
return$0>3
}
print("$0==== \(filteredNumbers)")
print("$1==== \(filteredNumbersD)")
/**
// 打印结果
$0==== [4, 5, 6]
$1==== [4, 5, 6]
*/
方法 map()
方法map()
方法map() 负责遍历集合中的每一个元素,对其进行操作,并形成一个新的集合,对元素的操作由闭包类型的参数提供
letdoubledNumbers = number.map{ (doubledNumbersT) ->Intin
returndoubledNumbersT *2
}
letdoubledNumbers2 = number.map{
return$0*2
}
print("doubledNumbers ==== \(doubledNumbers)")
print("doubledNumbers2==$0== \(doubledNumbers2)")
/**
// 打印结果
doubledNumbers ==== [2, 4, 6, 8, 10, 12]
doubledNumbers2==$0== [2, 4, 6, 8, 10, 12]
*/
//理解: (doubledNumbersT) -> Int in 相当于 $0
方法 reduce()
方法reduce()
/**
方法 reduce() 有二个参数:
第一个参数reduce(3)为整数,作为起始值 ,
第二个参数为闭包类型, 这闭包有二个参数:
第一个$0为当前值,另一个$1为集合中的一个元素值.闭包的返回值作为传给自己的当前值参数
*/
letdumOfNumbers = number.reduce(3) {
// 当前值=== (3)起始值 + $1中的元素值
print("dumOfNumbers =$0 当前值=== \($0) =$1=集合中的一个元素值 = \($1) ")
return$0+ $1
}
print("dumOfNumbers =结果值=== \(dumOfNumbers)")
/**
// 打印结果
dumOfNumbers =$0 当前值=== 3 =$1=集合中的一个元素值 = 1
dumOfNumbers =$0 当前值=== 4 =$1=集合中的一个元素值 = 2
dumOfNumbers =$0 当前值=== 6 =$1=集合中的一个元素值 = 3
dumOfNumbers =$0 当前值=== 9 =$1=集合中的一个元素值 = 4
dumOfNumbers =$0 当前值=== 13 =$1=集合中的一个元素值 = 5
dumOfNumbers =$0 当前值=== 18 =$1=集合中的一个元素值 = 6
dumOfNumbers =结果值=== 24
*/
二、第二篇 高级篇 - 枚举型
请查看下一篇文字...