檢視原始碼 基本類型

在本章節中,我們將進一步了解 Elixir 基本類型:整數、浮點數、布林值、原子和字串。其他資料類型,例如清單和元組,將在下一章節探討。

iex> 1          # integer
iex> 0x1F       # integer
iex> 1.0        # float
iex> true       # boolean
iex> :atom      # atom / symbol
iex> "elixir"   # string
iex> [1, 2, 3]  # list
iex> {1, 2, 3}  # tuple

基本算術

開啟 iex 並輸入以下表達式

iex> 1 + 2
3
iex> 5 * 5
25
iex> 10 / 2
5.0

請注意,10 / 2 傳回一個浮點數 5.0,而不是整數 5。這是預期的。在 Elixir 中,運算子 / 始終傳回浮點數。如果您想進行整數除法或取得除法餘數,您可以呼叫 divrem 函式

iex> div(10, 2)
5
iex> div 10, 2
5
iex> rem 10, 3
1

請注意,Elixir 允許您在呼叫需要一個或多個參數的函式時省略括號。此功能在撰寫宣告和控制流程結構時提供更簡潔的語法。然而,Elixir 開發人員通常偏好使用括號。

Elixir 也支援輸入二進位、八進位和十六進位數字的捷徑符號

iex> 0b1010
10
iex> 0o777
511
iex> 0x1F
31

浮點數需要一個點,後接至少一個數字,並且也支援 e 作為科學記號

iex> 1.0
1.0
iex> 1.0e-10
1.0e-10

Elixir 中的浮點數具有 64 位元精確度。

您可以呼叫 round 函式取得最接近給定浮點數的整數,或呼叫 trunc 函式取得浮點數的整數部分。

iex> round(3.58)
4
iex> trunc(3.58)
3

最後,我們使用不同的資料類型,我們將學習 Elixir 提供多個謂詞函式來檢查值的類型。例如,is_integer 可用於檢查值是否為整數

iex> is_integer(1)
true
iex> is_integer(2.0)
false

您也可以使用 is_floatis_number 分別檢查參數是否為浮點數,或整數或浮點數。

識別函式和文件

在我們繼續下一個資料類型之前,讓我們來討論 Elixir 如何識別函式。

Elixir 中的函式由其名稱和元數識別。函式的元數描述函式所使用的參數數量。從這一點開始,我們將同時使用函式名稱和其元數來描述整個文件中的函式。 trunc/1 識別的名稱為 trunc 的函式,並使用 1 個參數,而 trunc/2 識別一個不同的(不存在的)函式,名稱相同,但元數為 2

我們也可以使用此語法來存取文件。Elixir shell 定義了 h 函數,你可以使用它來存取任何函數的文件。例如,輸入 h trunc/1 將會列印 trunc/1 函數的文件

iex> h trunc/1
                             def trunc()

Returns the integer part of number.

h trunc/1 會運作是因為它是在 Kernel 模組中定義的。在 Kernel 模組中的所有函數都會自動匯入到我們的命名空間中。在尋找給定函數的文件時,你通常也會包含模組名稱

iex> h Kernel.trunc/1
                             def trunc()

Returns the integer part of number.

你可以使用模組+函數來查詢任何東西,包括運算子(試試 h Kernel.+/2)。呼叫沒有參數的 h 會顯示 IEx.Helpers 的文件,其中定義了 h 和其他功能。

布林值和 nil

Elixir 支援 truefalse 作為布林值

iex> true
true
iex> true == false
false

Elixir 也提供了三個布林運算子:or/2and/2not/1。這些運算子是嚴格的,因為它們期望第一個參數是評估為布林值(truefalse)的內容

iex> true and true
true
iex> false or is_boolean(true)
true

提供非布林值會引發例外

iex> 1 and true
** (BadBooleanError) expected a boolean on left-side of "and", got: 1

orand 是短路運算子。如果左側不足以確定結果,它們只會執行右側

iex> false and raise("This error will never be raised")
false
iex> true or raise("This error will never be raised")
true

Elixir 也提供了 nil 的概念,用來表示沒有值,以及一組也操作 nil 的邏輯運算子:||/2&&/2!/1。對於這些運算子,falsenil 被視為「假值」,所有其他值都被視為「真值」

# or
iex> 1 || true
1
iex> false || 11
11

# and
iex> nil && 13
nil
iex> true && 17
17

# not
iex> !true
false
iex> !1
false
iex> !nil
true

原子

原子是一個常數,其值就是其本身的名稱。其他語言會稱之為符號。它們通常用於列舉不同的值,例如

iex> :apple
:apple
iex> :orange
:orange
iex> :watermelon
:watermelon

如果原子的名稱相同,則它們相等。

iex> :apple == :apple
true
iex> :apple == :orange
false

它們通常用於表達操作的狀態,例如使用 :ok:error 等值。

布林值 truefalse 也是原子

iex> true == :true
true
iex> is_atom(false)
true
iex> is_boolean(:false)
true

Elixir 允許你省略 falsetruenil 原子的前導 :

字串

Elixir 中的字串以雙引號為界,並以 UTF-8 編碼

iex> "hellö"
"hellö"

注意:如果你在 Windows 上執行,你的終端機可能預設不使用 UTF-8。你可以在進入 IEx 之前執行 chcp 65001 來變更目前階段的編碼。

你可以使用 <>/2 算子串接兩個字串

iex> "hello " <> "world!"
"hello world!"

Elixir 也支援字串內插

iex> string = "world"
iex> "hello #{string}!"
"hello world"

字串串接要求兩邊都是字串,但內插支援任何可以轉換成字串的資料類型

iex> number = 42
iex> "i am #{number} years old!"
"i am 42 years old!"

字串可以包含換行符號。你可以使用跳脫序列來引入它們

iex> "hello
...> world"
"hello\nworld"
iex> "hello\nworld"
"hello\nworld"

你可以使用 IO.puts/1 函式從 IO 模組列印字串

iex> IO.puts("hello\nworld")
hello
world
:ok

請注意,IO.puts/1 函式在列印後會傳回原子 :ok

Elixir 中的字串在內部由稱為二進制檔的連續位元組序列表示

iex> is_binary("hellö")
true

我們也可以取得字串中的位元組數

iex> byte_size("hellö")
6

請注意,該字串中的位元組數為 6,即使它有 5 個字形。這是因為字形「ö」需要 2 個位元組才能以 UTF-8 表示。我們可以使用 String.length/1 函式根據字形數取得字串的實際長度

iex> String.length("hellö")
5

String 模組包含許多在 Unicode 標準中定義的字串操作函式

iex> String.upcase("hellö")
"HELLÖ"

結構比較

Elixir 也提供 ==!=<=>=<> 作為比較算子。我們可以比較數字

iex> 1 == 1
true
iex> 1 != 2
true
iex> 1 < 2
true

也可以比較原子、字串、布林值等

iex> "foo" == "foo"
true
iex> "foo" == "bar"
false

整數和浮點數如果值相同,則比較結果相同

iex> 1 == 1.0
true
iex> 1 == 2.0
false

但是,如果你想要區分整數和浮點數,可以使用嚴格比較算子 ===!==(這是這些算子之間唯一的差異)

iex> 1 === 1.0
false

Elixir 中的比較算子可以比較任何資料類型。我們說這些算子執行結構比較。有關更多資訊,你可以閱讀我們的 結構比較與語意比較 文件。

Elixir 也提供資料類型來表示集合,例如清單和元組,我們接下來會學習。當我們透過程序討論並行性和容錯時,我們也會討論埠、pid 和參考,但那將在後面的章節中討論。我們繼續前進。