鏈式比較

一起使用的多個比較運算子被連結,就像通過 && 運算子連線一樣 。這對於可讀和數學上簡潔的比較鏈非常有用,例如

# 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 > ca > 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)