Swift之||,&&,??的实现及原理
前言
上篇Swift中@autoclosure模拟了或运算,这篇继续探讨或运算,看看Swift中或运算是如何实现的。
或运算
下图是Playground中的或运算,没什么需要解释的。
1.png
点进去看下或运算是怎么实现的。
2.png只能看到这么个函数,这个函数有没有很眼熟,没错跟这篇Swift中@autoclosure文章中的差不多,只不过我没有用泛型而已。既然看不到实现,不防我们自己给他实现个。其实我们上篇文章中已经实现了,这里温习一下。
为了方便起见,我就不写||,写一个函数
func test<T : BooleanType>(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<T : BooleanType>(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!
}
调用一下看看结果如何
3.png
左边表达式的结果为true,所以第44行直接返回了结果,右边表达式没有判断,也没有必要判断。(这里不解释)
4.png
上面第一个表达式为false,直接return第二个表达式。后面的结果为true,也符合预期。 5.png
这个和图4一样,第一个表达式为false,直接返回第二个表达式。只不过这里第二个表达式是false。
有人可能会提出这样的疑问,为什么系统方法是这么调用的
1>2 || 2<3
你的却是这样调用的
test(1>2, rhs: 2<3)
因为我是用普通的函数实现的,系统的是用运算符实现的。我们点进去看下文档有什么不一样的。
运算符
6.png搜一下,哎,果然有点线索。再找找。
7.png好家伙,要的就是这句话。 operator不就是运算符吗(英语还不错)。而且每个都有precedence一个数字,而且数字有大有小都不一样,如果没猜错的话应该就是表示优先级的。每个前面还有个infix,这是什么呢?(英语大神不要鄙视,我英语六级都没过,这个单词真不认识)再往下翻翻。
8.png
好家伙,pre这个我能看懂,"!"取非运算符前面是pre,是运算符在前面的,只有后面有表达式。那infix应该就是中位运算符,前后都有表达式。associativity(结合性),就是结合律了,左结合,右结合。
废话有点多了,知道怎么回事,开始实现吧
为了与系统||运算符区分开来,我们用|||多写一个竖线。
很简单,照抄一遍,就是多加一个“|”
完美实现,跟系统的效果一样
看下手写代码
func |||<T : BooleanType>(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
总结
关于&&和??这里就不再写了,想要代码的话,可以在评论里留言。(建议最好自己写一遍)