美文网首页
swift基础——闭包

swift基础——闭包

作者: 李永开 | 来源:发表于2023-02-14 15:56 被阅读0次

一. 闭包简介

  • 一个函数和它所捕获的变量/常量环境组合起来,成为闭包
  • 如果闭包捕获了局部变量,那么会将该局部变量保存到堆空间
  • 闭包和类非常相似,捕获的局部变量在堆空间,前16个字节储存基本信息

二. 测试一下

普通闭包

//正常函数
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 sub(_ a: Int) -> (Int) {
        num1 -= a
        return num1
    }
    
    return (add, sub)
}
let (add, sub) = moreClosure()
add(10)         //10
sub(3)          //7
add(10000)      //10007
// 当两个闭包同时引用一个局部变量时,不会创建两个堆空间来保存该变量,而是共用一个变量
// 闭包捕获的局部变量在堆空间,前16个字节储存基本信息

自动闭包


//: # 自动闭包
//: * @autoclosure 主要是用来优化性能的,避免多余的计算之类,有可能会延迟调用
//: * @autoclosure只支持无参的闭包表达式,而且必须有返回值,局限性比较大
//: * @autoclosure支持重载

总的来说:自动闭包就是把普通值包装成闭包,可以在函数内部决定闭包调用时机(鸡肋🐔)

//@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})//10大于0了,期望不执行后面的闭包,所以就有了可以延迟调用的闭包(自动闭包)
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()) //会打印


// ?? 就是基于自动闭包实现的, 下面就是他的实现
//public func ?? <T>(optional: T?, defaultValue: @autoclosure () throws -> T?) rethrows -> T?

相关文章

  • Swift 基本语法(函数, 闭包)

    前言 接上篇, 这篇聊一下 Swift中的 函数, 闭包 一 函数 二 闭包 Swift 基础 先介绍三篇, ...

  • 托XX福写个Swift闭包教程

    闭包基础知识 Swift闭包和OC的block类似不过还是有点区别 OC的block是一个匿名函数 Swift 中...

  • Swift3.0_闭包(Closure)

    闭包基础 ** 闭包是自包含的函数代码块,可以在代码中被传递和使用。Swift 中的闭包与 C 和 Objecti...

  • Swift-闭包

    Swift 闭包 函数 ()->() Swift 中的闭包和 Objective-C 中的 block 类似,闭包...

  • Swift闭包和函数

    函数在Swift中只是一种特殊的闭包,闭包在Swift语言中是一等公民,支持闭包嵌套和闭包传递。Swift中的闭包...

  • Swift基础-- 闭包

    一,闭包的定义 闭包是自包含的函数代码块,可以在在代码中被传递和使用。 闭包能捕获和存储骑在上下文中任意常量和变量...

  • swift - 闭包基础

    闭包 closure 闭包在Swift中应用广泛,在许多系统库方法中都能看到。 无名本质是函数使用时注意循环引用 ...

  • Swift基础--闭包

    闭包表达式语法 闭包表达式语法有如下的一般形式: 1 { (parameters) -> (return type...

  • Swift基础 : 闭包

    Swift 闭包 闭包(Closures)是包含功能的代码块, 可以在代码中使用或者用来作为参数传值 闭包的定义:...

  • swift基础-闭包

    一,Block的回顾 1,Block通常会用在网络请求中,请求到数据后然后回调,先自定义HttpTool的工具类实...

网友评论

      本文标题:swift基础——闭包

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