鏈式比較
一起使用的多個比較運算子被連結,就像通過 &&
運算子連線一樣 。這對於可讀和數學上簡潔的比較鏈非常有用,例如
# same as 0 < i && i <= length(A)
isinbounds(A, i) = 0 < i ≤ length(A)
# same as Set() != x && issubset(x, y)
isnonemptysubset(x, y) = Set() ≠ x ⊆ y
然而,a > b > c
和 a > b && b > c
之間有一個重要的區別; 在後者中,術語 b
被評估兩次。這對於普通的舊符號來說並不重要,但如果術語本身具有副作用則可能很重要。例如,
julia> f(x) = (println(x); 2)
f (generic function with 1 method)
julia> 3 > f("test") > 1
test
true
julia> 3 > f("test") && f("test") > 1
test
test
true
讓我們通過檢視它們如何被解析並降低到表示式中來深入研究鏈式比較及其工作原理。首先,考慮簡單的比較,我們可以看到它只是一個普通的舊函式呼叫:
julia> dump(:(a > b))
Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol >
2: Symbol a
3: Symbol b
typ: Any
現在,如果我們連結比較,我們注意到解析已經改變:
julia> dump(:(a > b >= c))
Expr
head: Symbol comparison
args: Array{Any}((5,))
1: Symbol a
2: Symbol >
3: Symbol b
4: Symbol >=
5: Symbol c
typ: Any
解析後,表示式然後降低到最終形式:
julia> expand(:(a > b >= c))
:(begin
unless a > b goto 3
return b >= c
3:
return false
end)
我們確實注意到這與 a > b && b >= c
相同:
julia> expand(:(a > b && b >= c))
:(begin
unless a > b goto 3
return b >= c
3:
return false
end)