swift基础_函数

2022-04-11  本文已影响0人  李永开

一.闭包简介

//正常函数
func funcAdd (_ a: Int, _ b: Int) -> Int{
    a + b
}

//闭包表达式
var closure = {
    (a : Int, b : Int) -> Int in
    return a + b
}

//匿名闭包
//{
//    (a : Int, b : Int) -> Int in
//    return a + b
//}(10, 20)


funcAdd(1, 5)
closure(1, 5)

二.尾随闭包

尾随闭包是一个被书写在函数调用括号外面的闭包表达式,使用尾随闭包增强函数的可读性

//尾随闭包是一个被书写在函数调用括号外面的闭包表达式,使用尾随闭包增强函数的可读性
func exe(a: Int, b: Int, closure:(Int, Int)->Int) {
    print(closure(a, b))
}
exe(a:100, b:1, closure:{a, b -> Int in return a + b})  //原始
exe(a:100, b:1, closure:{a, b -> Int in a + b})         //简化,去掉return
exe(a:100, b:1, closure:{$0 + $1})                      //简化,去掉a,b
exe(a:100, b:1, closure:+)                              //简化,直接用+

//使用尾随闭包, 就是将最后一个闭包在参数项后面展开
exe(a:100, b:1) {
    $0+$1
}

//如果闭包是函数的唯一实参,而且使用了尾随闭包的方式,那么可以简写
func exeSimple(closure:(Int, Int)->Int) {
    print(closure(1, 2))
}
exeSimple(closure: {a, b -> Int in return a + b})
exeSimple(){
    $0 + $1
}
exeSimple{$0 + $1}

//测试demo
var arr = [1, 3, 8, 2, 7, 6]
print(arr.sorted())
//print(arr.sorted(by: <#T##(Int, Int) throws -> Bool#>))
print(arr.sorted{$0 > $1})

三. 闭包测试

//----------------------------- 1-------------------------------
func retClosure() -> (Int)->Int {
    var num = 100
    
    func innerClo(_ a: Int) -> Int {
        num += a
        return num
    }
    return innerClo
}
retClosure()(1) //101
retClosure()(2) //102
retClosure()(3) //103
//num并没有累加

//----------------------------- 2-------------------------------
//换一种调用方式,num累加了,说明它捕获了num,并且一直再使用这个num
typealias fn = (Int)->Int
var fff = retClosure()
fff(1)         //101
fff(2)         //103
fff(3)         //106


//----------------------------- 3-------------------------------
var num = 100
func retClosureOut() -> (Int)->Int {
    
    func innerClo(_ a: Int) -> Int {
        num += a
        return num
    }
    return innerClo
}
retClosureOut()(1) //101
retClosureOut()(2) //103
retClosureOut()(3) //106
//把num放到了外面,num累加



//----------------------------- 4-------------------------------
func retClosureChangeNum() -> (Int)->Int {
    var num = 100
    
    func innerClo(_ a: Int) -> Int {
        num += a
        return num
    }
    
    num = 200
    return innerClo
}
retClosureChangeNum()(1) //201   很神奇,闭包捕获变量是在return 之前. 所以第一个100被200替换了



//----------------------------- 5-------------------------------
typealias retfn = (Int)->Int

func moreClosure() ->(retfn, retfn) {
    var num1 = 0
    
    func add(_ a: Int) -> (Int) {
        num1 += a
        return num1
    }
    
    func sum(_ a: Int) -> (Int) {
        num1 -= a
        return num1
    }
    
    return (add, sum)
}
let (add, sum) = moreClosure()
add(10)         //10
sum(3)          //7
add(10000)      //10007
// 当两个闭包同时引用一个局部变量时,不会创建两个堆空间来保存该变量,而是共用一个变量

四.自动闭包

//@autoclosure
func getFirstNum1(_ a: Int, _ b: Int) -> Int {
    a > 0 ? a : b
}
func getFirstNum2(_ a: Int, _ b: ()->Int) {
    a > 0 ? a : b()
    print(a)
}
getFirstNum2(10,{() -> Int in return 20})
getFirstNum2(10,{20})
getFirstNum2(10){20}

//加上@autoclosure自动闭包,可以不写{}了  -> 编译器特性,自动加了{}
func getFirstNum3(_ a: Int, _ b: @autoclosure ()->Int) {
    a > 0 ? a : b()
    print(a)
}
getFirstNum3(10,20)


let getNumFor4 = {()->Int in
    let a = 100
    let b = 200
    print("这行会走吗?")
    return a + b
}
func getFirstNum4(_ a: Int, _ b: @autoclosure ()->Int) {
    a > 0 ? a : b()
    print(a)
}
getFirstNum4(10, getNumFor4()) //加了@autoclosure后,编译器发现10 > 0, 所以就不会调用getNumFor4这个闭包表达式,节省了性能(延迟执行)
getFirstNum4(-10, getNumFor4()) //会打印

五.逃逸闭包

Final

上一篇 下一篇

猜你喜欢

热点阅读