Swift之||,&&,??的实现及原理

前言

上篇Swift中@autoclosure模拟了或运算,这篇继续探讨或运算,看看Swift中或运算是如何实现的。

或运算

下图是Playground中的或运算,没什么需要解释的。


1.png

点进去看下或运算是怎么实现的。

2.png

只能看到这么个函数,这个函数有没有很眼熟,没错跟这篇 Swift中@autoclosure文章中的差不多,只不过我没有用泛型而已。既然看不到实现,不防我们自己给他实现个。其实我们上篇文章中已经实现了,这里温习一下。
为了方便起见,我就不写||,写一个函数

func test(lhs: T, @autoclosure rhs: () throws -> Bool) rethrows -> Bool {
    if lhs {
        return true
    }
    do {
       return try rhs()
    } catch {
        return false
    }
}

右边表达式有throws关键字,是要做异常处理的,这是swift2.0加的异常处理,这也是为什么很多从网上下载下来的代码,以前用if else的那些,现在好多都不能用,报错的原因。关于异常处理,自行百度吧,网上一堆。其实这里是偷懒的做法,catch里应该做一场处理,不是直接返回false,下面给个参考做法,之后的就不做一场处理了。(偷个懒)

func test(lhs: T, @autoclosure rhs: () throws -> Bool) rethrows -> Bool {
    if lhs {
        return true
    }
    var error:NSError
    var result:Bool?
    do {
       result = try rhs()
    } catch let error1 as NSError {
        error = error1
        print("\(error.userInfo)")
    }
    return result!
}

调用一下看看结果如何


Swift之||,&&,??的实现及原理_第1张图片
3.png

左边表达式的结果为true,所以第44行直接返回了结果,右边表达式没有判断,也没有必要判断。(这里不解释)


Swift之||,&&,??的实现及原理_第2张图片
4.png

上面第一个表达式为false,直接return第二个表达式。后面的结果为true,也符合预期。
Swift之||,&&,??的实现及原理_第3张图片
5.png

这个和图4一样,第一个表达式为false,直接返回第二个表达式。只不过这里第二个表达式是false。
有人可能会提出这样的疑问,为什么系统方法是这么调用的

1>2 || 2<3

你的却是这样调用的

test(1>2, rhs: 2<3)

因为我是用普通的函数实现的,系统的是用运算符实现的。我们点进去看下文档有什么不一样的。

运算符

Swift之||,&&,??的实现及原理_第4张图片
6.png

搜一下,哎,果然有点线索。再找找。

7.png

好家伙,要的就是这句话。 operator不就是运算符吗(英语还不错)。而且每个都有precedence一个数字,而且数字有大有小都不一样,如果没猜错的话应该就是表示优先级的。每个前面还有个infix,这是什么呢?(英语大神不要鄙视,我英语六级都没过,这个单词真不认识)再往下翻翻。


Swift之||,&&,??的实现及原理_第5张图片
8.png

好家伙,pre这个我能看懂,"!"取非运算符前面是pre,是运算符在前面的,只有后面有表达式。那infix应该就是中位运算符,前后都有表达式。associativity(结合性),就是结合律了,左结合,右结合。

废话有点多了,知道怎么回事,开始实现吧
为了与系统||运算符区分开来,我们用|||多写一个竖线。
很简单,照抄一遍,就是多加一个“|”

Swift之||,&&,??的实现及原理_第6张图片
9.png

完美实现,跟系统的效果一样
看下手写代码

func |||(lhs: T, @autoclosure rhs: () throws -> Bool) rethrows -> Bool {
    if lhs {
        return true
    }
    
    do {
        return try rhs()
    } catch {
        return false
    }
}

infix operator ||| {
    associativity left
    precedence 110
}

1<2 ||| 2>3
1<2 ||| 2<3
1>2 ||| 2>3

总结

关于&&和??这里就不再写了,想要代码的话,可以在评论里留言。(建议最好自己写一遍)

你可能感兴趣的:(Swift之||,&&,??的实现及原理)