變數

在 Julia 中,變數是一個與值關聯 (或繫結) 的名稱。當您想要儲存一個值 (例如,在一些數學運算後取得的值) 以供稍後使用時,這會很有用。例如

# Assign the value 10 to the variable x
julia> x = 10
10

# Doing math with x's value
julia> x + 1
11

# Reassign x's value
julia> x = 1 + 1
2

# You can assign values of other types, like strings of text
julia> x = "Hello World!"
"Hello World!"

Julia 提供了一個極為彈性的變數命名系統。變數名稱區分大小寫,且沒有語義意義 (亦即,語言不會根據變數的名稱對變數進行不同的處理)。

julia> x = 1.0
1.0

julia> y = -3
-3

julia> Z = "My string"
"My string"

julia> customary_phrase = "Hello world!"
"Hello world!"

julia> UniversalDeclarationOfHumanRightsStart = "人人生而自由,在尊严和权利上一律平等。"
"人人生而自由,在尊严和权利上一律平等。"

允許使用 Unicode 名稱 (以 UTF-8 編碼)

julia> δ = 0.00001
1.0e-5

julia> 안녕하세요 = "Hello"
"Hello"

在 Julia REPL 和其他幾個 Julia 編輯環境中,您可以透過輸入反斜線 LaTeX 符號名稱後按 Tab 鍵來輸入許多 Unicode 數學符號。例如,變數名稱 δ 可以透過輸入 \delta-Tab,甚至 α̂⁽²⁾ 可以透過 \alpha-Tab-\hat- Tab-\^(2)-Tab 來輸入。(如果您在某個地方 (例如,在別人的程式碼中) 找到一個符號,但不知道如何輸入,REPL 說明會告訴您:只要輸入 ?,然後貼上符號即可。)

如果需要,Julia 甚至允許您重新定義內建常數和函數(儘管不建議這樣做,以避免潛在的混淆)

julia> pi = 3
3

julia> pi
3

julia> sqrt = 4
4

但是,如果您嘗試重新定義已使用的內建常數或函數,Julia 會給您一個錯誤

julia> pi
π = 3.1415926535897...

julia> pi = 3
ERROR: cannot assign a value to imported variable Base.pi from module Main

julia> sqrt(100)
10.0

julia> sqrt = 4
ERROR: cannot assign a value to imported variable Base.sqrt from module Main

允許的變數名稱

變數名稱必須以字母(A-Z 或 a-z)、底線或大於 00A0 的 Unicode 碼點子集開頭;特別是,Unicode 字元類別 Lu/Ll/Lt/Lm/Lo/Nl(字母)、Sc/So(貨幣和其他符號)和一些其他類似的字母字元(例如 Sm 數學符號的子集)是允許的。後續字元還可以包含!和數字(0-9 和類別 Nd/No 中的其他字元),以及其他 Unicode 碼點:變音符號和其他修飾符號(類別 Mn/Mc/Me/Sk)、一些標點符號連接符(類別 Pc)、質數和一些其他字元。

+ 這樣的運算子也是有效的識別符號,但會特別解析。在某些情況下,運算子可以像變數一樣使用;例如 (+) 參照加法函數,而 (+) = f 將重新指派它。大多數 Unicode 中綴運算子(在類別 Sm 中),例如 ,都被解析為中綴運算子,並且可供使用者定義的方法使用(例如,您可以使用 const ⊗ = kron 定義為中綴克羅內克積)。運算子也可以加上修飾符號、質數和上/下標,例如 +̂ₐ″ 被解析為與 + 具有相同優先順序的中綴運算子。在以上下標字母結尾的運算子與後續變數名稱之間需要一個空格。例如,如果 +ᵃ 是運算子,則 +ᵃx 必須寫成 +ᵃ x 以區別於 + ᵃx,其中 ᵃx 是變數名稱。

特定類別的變數名稱只包含底線。這些識別碼只能指定值,且會立即捨棄,因此無法用來指定其他變數的值(亦即,無法用作 rvalues)或以任何方式使用指定給它們的最後一個值。

julia> x, ___ = size([2 2; 1 1])
(2, 2)

julia> y = ___
ERROR: syntax: all-underscore identifier used as rvalue

julia> println(___)
ERROR: syntax: all-underscore identifier used as rvalue

變數唯一明確不允許的名稱是內建 關鍵字 的名稱

julia> else = false
ERROR: syntax: unexpected "else"

julia> try = "No"
ERROR: syntax: unexpected "="

某些 Unicode 字元在識別碼中被視為等效。輸入 Unicode 結合字元(例如重音)的不同方式被視為等效(特別是,Julia 識別碼是 NFC。Julia 也包含一些非標準等效,用於視覺上相似且容易透過某些輸入法輸入的字元。Unicode 字元 ɛ (U+025B:拉丁小寫字母開 e)和 µ (U+00B5:微號)被視為等效於對應的希臘字母。中點 · (U+00B7) 和希臘 間隔號 · (U+0387) 都被視為數學點運算子 (U+22C5)。減號 (U+2212) 被視為等效於連字號減號 - (U+002D)。

指定運算式和指定相對於變異

指定 變數 = 值 會將名稱 變數 「繫結」到右手邊計算的 ,而整個指定會被 Julia 視為等於右手邊 的表達式。這表示指定可以「串接」(將同一個 指定給多個變數,例如 變數1 = 變數2 = 值)或用於其他表達式,這也是為什麼它們的結果會在 REPL 中顯示為右手邊的值。(一般來說,REPL 會顯示您評估的任何表達式的值。)例如,這裡 b = 2+2 的值 4 用於另一個算術運算和指定

julia> a = (b = 2+2) + 3
7

julia> a
7

julia> b
4

常見的混淆是區分指定(給予值一個新的「名稱」)和變異(變更值)。如果您執行 a = 2 後面接著 a = 3,您已經將「名稱」a 變更為參考新值 3 … 您沒有變更數字 2,所以 2+2 仍然會得到 4 而不是 6!當處理像 陣列 之類的可變類型時,這個區別會更明顯,其內容可以被變更

julia> a = [1,2,3] # an array of 3 integers
3-element Vector{Int64}:
 1
 2
 3

julia> b = a   # both b and a are names for the same array!
3-element Vector{Int64}:
 1
 2
 3

這裡,程式碼行 b = a 不會複製陣列 a,它只是將名稱 b 繫結到同一個陣列 aba 都「指向」記憶體中的一個陣列 [1,2,3]。相反地,指定 a[i] = 值變更陣列的內容,而修改後的陣列會透過名稱 ab 都看得見

julia> a[1] = 42     # change the first element
42

julia> a = 3.14159   # a is now the name of a different object
3.14159

julia> b   # b refers to the original array object, which has been mutated
3-element Vector{Int64}:
 42
  2
  3

亦即,a[i] = valuesetindex! 的別名)會變異記憶體中現有的陣列物件,可透過 ab 存取。隨後設定 a = 3.14159 並不會變更此陣列,它僅將 a 繫結到不同的物件;陣列仍可透過 b 存取。變異現有物件的另一種常見語法為 a.field = valuesetproperty! 的別名),可用於變更 mutable struct

在 Julia 中呼叫 函式 時,其行為就像將引數值指派給對應於函式引數的新變數名稱,如 引數傳遞行為 中所述。(依 慣例,會變異其一個或多個引數的函式其名稱會以 ! 結尾。)

風格慣例

雖然 Julia 對有效名稱的限制很少,但採用下列慣例已變得很有用

  • 變數名稱使用小寫字母。
  • 字詞分隔可用底線 ('_') 表示,但除非名稱在沒有底線的情況下難以閱讀,否則不建議使用底線。
  • TypeModule 的名稱以大寫字母開頭,字詞分隔以大寫駝峰式表示,而非底線。
  • functionmacro 的名稱使用小寫字母,沒有底線。
  • 會寫入其引數的函式其名稱會以 ! 結尾。這些函式有時稱為「變異」或「原地」函式,因為它們在呼叫函式後會對其引數產生變更,而不仅仅是傳回一個值。

有關風格慣例的更多資訊,請參閱 風格指南