Swift @autoclosure关键字的用法及场景

本文介绍了Swift中的@autoclosure关键字,它允许将参数自动封装为闭包,实现延迟执行。通过一个示例,解释了在避免数组越界检查时如何使用@autoclosure,以及在系统函数如??运算符中应用此特性的原因,强调了延迟执行对于性能优化和防止意外执行的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

@autoclosure及自动封装成闭包

我们先模拟一个场景 创建一个数组 我们先判断数组是否为空,再去判断他下标为0的元素是否为0
显然这段场景需要先执行第一步才能再执行第二步 否则数组会出现越界
我们使用下面代码

let num = [Int]()
//这里第一个条件判断出有问题就不会执行第二个操作了 这样就不会越界了
if !num.isEmpty && num[0]>0{
    
}

这里是没有问题的

现在我们想设置一个函数 ,来代替&&的操作

func judgeTwice ( a : Bool , b : @autoclosure ()-> Bool) -> Bool{

    func judgeTwice (_ a : Bool ,_ b :Bool) -> Bool{
        print("judgeTwice start working")
    guard a else {
        return false
    }
    return b
}

if judgeTwice(!num.isEmpty,num[0]>0) {

}

这里就报错了 原因是num[0]>0在执行第一个!num.isEmpty参数的情况下就被执行了,控制台也没有打印消息,说明这个函数并没有被调用就已经崩溃了 。
我们可以得出结论函数使用的时候系统先去会编译一次函数的参数,去看其是否越界之类。
如果想要参数在函数中再去执行,我们就可以使用闭包的方法,把条件封装起来,不然系统检查到越界,因为我们在函数中可以保证使用的时候不会出现越界问题。
我们修改一下上面代码

  func judgeTwice (_ a : Bool ,_ b :()-> Bool) -> Bool{
        print("judgeTwice start working")
    guard a else {
        return false
    }
    return b()
}
//这里我们要把参数封装成一个闭包
if judgeTwice(!num.isEmpty,{return num[0]>0}) {

}

这样系统就不会报错了 而且judgeTwice方法也被调用了
但是每次都要把该参数封装一下 十分麻烦 于是系统帮我们发明了@autoclosure关键字 ,作用就是我们只要把参数放进去系统会自动帮我们封装成闭包。这样就可以达到参数的延迟执行,而且也可以享受延迟执行的性能优化,num[0]>0 变成{return num[0]>0}
上面代码更改成最终模式

func judgeTwice (_ a : Bool ,_ b :@autoclosure ()-> Bool) -> Bool{
        print("judgeTwice start working")
    guard a else {
        return false
    }
    return b()
}

if judgeTwice(!num.isEmpty,num[0]>0) {

}

这使用起来就会很方便了
还有 系统中一般对函数的参数判断有要求的都会采用闭包,否则的话参数会在调试阶段就被调用一次。
@autoclosure在系统函数中经常看到
比如??运算符,显然这是个二项运算符要传入两个左右参数,
想一下这个场景a??b,显然你不想在a判断是否有值前就去执行一次b操作了把 ,b需要延迟执行,这个延迟条件取决于a。所以系统对这个运算符的右边参数是进行了@autoclosure封装的,延迟执行的重要性体现在假如b里面的操作是涉及引用计数器相关的操作,如果被多执行一次会造成巨大的bug,所以要使用到@autoclosure

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值