闭包

2018-12-10  本文已影响0人  架构师的一小步
闭包:自包含的代码块,可以在代码中被传递和使用

(s1:String, s2:String) -> Bool in return s1<s2 } //闭包

闭包的三种形式

闭包表达式语法

闭包简化写法

let names=["Zhao","Sun","Qian","D"]


func comparator(s1:String,s2:String) ->Bool{
    return s1<s2
}

//对字符串按照大小进行排序
var sortedNames=names.sorted{$0<$1}

print(sortedNames)

var newNames=names.sorted(by: comparator)
newNames=names.sorted(by: { (s1:String,s2:String) ->Bool in return s1<s2 })

newNames=names.sorted(by: {s1,s2 in return s1<s2})

newNames=names.sorted(by: {s1,s2 in s1<s2})

newNames=names.sorted(by: {$0<$1})

newNames=names.sorted(){$0<$1}

newNames=names.sorted {$0<$1}

newNames=names.sorted  (by: <)

简略写法2

/**
 * 函数简略写法
 */

func calculate(a:Int,b:Int,mathFunction:(Int,Int)->Int)->Int{
    return mathFunction(a,b)
}

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

var door=calculate(a: 3, b: 5, mathFunction: {(a:Int,b:Int)->Int in return a+b})//一行代码 将addTwoInts闭包放到这个函数内

 door=calculate(a: 3, b: 5, mathFunction: {a,b in return a+b})//根据上下文推断类型

 door=calculate(a: 3, b: 5, mathFunction: {a,b in a+b}) //但表达式闭包隐式返回

 door=calculate(a: 3, b: 5, mathFunction: {$0+$1})//参数名称缩写

 door=calculate(a: 3, b: 5) {$0+$1}  //尾随闭包方式

//添加新的方法
door=calculate(a: 3, b: 5) {$0*$1}//乘法

door=calculate(a: 3, b: 5) {$0*$0*$1} //第一个参数乘两次再乘第二个参数

高阶函数

map

/**
 * 高阶函数
 */

//1.map 用来对数组元素进行某种规则的转换
let numbers = [1,2,3,4]
//需求:1.将numbers数组里的值全变成第..个   2.将数组值变成11,12,13,14
//解决方案:map
//1.完整写法
let numbersName=numbers.map { (element:Int) -> String in
    return "第"+String(element)+"个"
}
print(numbersName)//["第1个", "第2个", "第3个", "第4个"]
//1.简略写法
let numbersName1=numbers.map{"第"+String($0)+"个"}//尾随闭包+参数名缩写
print(numbersName1)//["第1个", "第2个", "第3个", "第4个"]

//2.完整写法
let newNubers = numbers.map { (element:Int) -> Int in
    return element+10
}
print(newNubers)//[11, 12, 13, 14]
//2.简略写法
let newNumbers=numbers.map{$0+10}
print(newNumbers)//[11, 12, 13, 14]

reduce:对数组元素进行某种规则的归纳

/**
 * 高阶函数
 */

//reduce

//1.累加 2.累乘
let numbers=[1,2,3,4]
//1.完整写法需要设置初始值这里加法所以设置0 期望结果:1+2+3+4=10  这里设置成0实际结果是0+1+2+3+4=10
var reduceResult=numbers.reduce(0){(prevSum:Int, element:Int) in prevSum+element}
//$0指之前的归纳值 1.简略写法
reduceResult=numbers.reduce(0){$0+$1}//10

print(reduceResult)

//2.完整写法,这里设置成1,实际运算是1*1*2*3*4=24
reduceResult=numbers.reduce(1){(prevSum:Int, element:Int) in prevSum*element}

//2.简略写法
reduceResult=numbers.reduce(1){$0*$1}
print(reduceResult)//24

filter:对数组元素进行某种规则的过滤

/**
 * 高阶函数
 */

//需求:过滤出其中的偶数
let numbers=[1,2,3,4,44,55,66,789,1123,2018]
//符合偶数的数提取出来存入evens
var evens=numbers.filter{(element:Int) in return (element%2==0)}

evens=numbers.filter{element in element%2==0}

evens=numbers.filter{$0%2==0}

print(evens)//[2, 4, 44, 66, 2018]

//符合偶数的数提取出来存入evens
evens=numbers.filter{(element:Int) in return (element%2==1)}

evens=numbers.filter{$0%2==1}

print(evens)//[1, 3, 55, 789, 1123]

捕获值(capturing values)

嵌套函数可以随时获取amount,runingTotal和incrementor函数的值
//嵌套函数
func makeIncrementor(forIncrement amount:Int)->() ->Int{
    var runningTotal = 0
    func incrementor() ->Int {
        runningTotal += amount
        return runningTotal
    }
    return incrementor
}

let incrementByTen=makeIncrementor(forIncrement: 10)
print(incrementByTen())//10
//将这个incrementByTen这个函数赋值给anotherIncrementByTen,调用anotherIncrementByTen会在incrementByTen的值为10的基础上进行继续计算
let anotherIncrementByTen=incrementByTen
print(anotherIncrementByTen())//20
//如果直接调用makeIncrementor这个函数值会重新开始计算
let therdIncrementByTen=makeIncrementor(forIncrement: 10)
print(therdIncrementByTen())//10

这里incrementByTen调用完闭包之后,another...ByTen调用这个闭包,因为这个闭包是引用类型,多以他们指向了同一个地址, 闭包维护了内部的函数和自由变量,第二个函数调用会在原来的基础上进行累计

逃逸闭包

闭包使用场景

需要加@escaping关键字的闭包逃逸场景
上一篇下一篇

猜你喜欢

热点阅读