做Swift Switch短路吗?
开关语句有多个评估短路吗?做Swift Switch短路吗?
这可能没关系,但我很好奇。
这里有一个简单的例子:
let one = 1
let two = true
let three = false
switch (one, two, three) {
case let (0, b, c) where b==c:
break
case (0, true, true):
break
default:
break
}
在第一个case语句,将在 '地点' 的评价,甚至发生?
在第二种情况下,'two'== true会发生吗?
@ J.beenie的答案很好地(和令人信服地)对待你的第一个问题。 b == c
将不会被调用,因为您的初始one
不匹配0
,经典AND
短路。
你的第二个问题取决于元组的==
的实现。根据a comment to this question,自从2.2.1版本以来,这已经是Swift语言的一部分,并且标准实现当然是短路的,因为它是最快速的事情。所以在第二种情况下,第二个元素不会被比较。
顺便说一句:你不需要break
在一个Swift switch
声明,而不是你想fallthrough
,如果你需要的话。
纠错: 我的猜测证明只是一半正确。在switch
声明中的模式匹配似乎比我预期的要多。我试图用我自己的Bool
枚举(大致如下this post(和调整斯威夫特3))劫持==
,并得到了一些令人惊讶的结果:
import Cocoa
let one = 1
let two:MyBool = .myTrue
let three:MyBool = .myFalse
typealias ThreeTuple = (o:Int, tw:MyBool, th:MyBool)
let tuple:ThreeTuple
tuple = (one, two, three)
switch tuple {
case let (1, b, c) where b == c:
print("first case")
case (1, .myTrue, .myFalse):
print("second case")
default:
print("default")
}
enum MyBool : ExpressibleByBooleanLiteral, Equatable {
case myTrue, myFalse
public init() { self = .myFalse }
public init(booleanLiteral value: BooleanLiteralType) {
self=value ? .myTrue : .myFalse
}
}
func ==(lhs: MyBool, rhs: MyBool) -> Bool {
print("evaluate ==")
switch (lhs, rhs) {
case (.myTrue,.myTrue), (.myFalse,.myFalse):
return true
default:
return false
}
}
这将产生
evaluate ==
second case
在这一点上,我majorly惊讶。 ==
对MyBool
值的唯一评估值来自第一个case
中的where b == c
子句,并且所有元组“比较”都不使用MyBool
==
函数根本没有 !!我怀疑优化器进行干扰,所以我变成了switch
成func
作为
func match(_ tuple:ThreeTuple) {
switch tuple {
case let (1, b, c) where b == c:
print("first case")
case (1, .myTrue, .myFalse):
print("second case")
default:
print("default")
}
}
应排除在编译时过度优化,但是当我要求现在
match((1, .myTrue, .myTrue))
match((1, .myTrue, .myFalse))
match((0, .myTrue, .myFalse))
我得到
evaluate ==
first case
evaluate ==
second case
default
其中evaluate ==
仍然只来自第一个case
。因此,唯一合理的结论似乎是在switch
声明中的模式匹配过程中发生了“其他一些魔法”。我试图谷歌,如果我能弄清楚那是什么,但目前为止无济于事。无论如何,似乎有方式更多的短路超出我的预期。
测试你用下面的代码问题:
let one = 1
let two = true
let three = false
switch (one, two, three) {
case let (0, b, c) where b - c:
break
case (0, true, true):
break
default:
break
}
extension Bool{
static func - (lhs: Bool, rhs: Bool) -> Bool {
print("foo")
return lhs == rhs
}
}
在操场
只是改变了第一个0到1,看看会发生什么。
答案是肯定的;)确实短路。
写一些代码来证明第二种情况也是很酷的短路。不能弄清楚如何做到这一点。 –
@ J.beenie你是对的,似乎还有其他事情正在发生,模式匹配似乎在* Swift中*真正优化*(TM)。让我们看看是否有人能够对此有所了解。 – Patru