當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


Elixir IO用法及代碼示例


Elixir語言中 IO 相關用法介紹如下。

處理輸入/輸出 (IO) 的函數。

該模塊中的許多函數都需要一個 IO 設備作為參數。 IO 設備必須是 PID 或代表進程的原子。為方便起見,Elixir 提供了 :stdio:stderr 作為 Erlang 的 :standard_io:standard_error 的快捷方式。

大多數函數都需要 chardata。如果給出了另一種類型,函數將通過 String.Chars 協議將這些類型轉換為字符串(如 typespecs 中所示)。有關 chardata 的更多信息,請參閱下麵的 "IO data" 部分。

IO 設備

IO 設備可以是原子或 PID。如果它是原子,則原子必須是已注冊進程的名稱。此外,Elixir 提供了兩個快捷鍵:

  • :stdio - :standard_io 的快捷方式,映射到 Erlang 中的當前 Process.group_leader/0

  • :stderr - Erlang 中提供的命名進程 :standard_error 的快捷方式

IO 設備保持其位置,這意味著對任何讀取或寫入函數的後續調用將從上次訪問設備的位置開始。可以使用 :file.position/2 函數更改文件的位置。

IO數據

IO 數據是一種數據類型,在某些情況下可用作二進製文件的更有效替代方案。

IO 數據類型的術語是包含字節(0..255 範圍內的整數)或嵌套 IO 數據的二進製或列表。類型是遞歸的。讓我們看一個表示二進製 "hello" 的可能 IO 數據的示例:

[?h, "el", ["l", [?o]]]

內置 iodata/0 類型是根據 iolist/0 定義的。 IO 列表與 IO 數據相同,但它不允許在頂層使用二進製文件(但列表本身仍允許使用二進製文件)。

IO 數據用例

IO 數據之所以存在,是因為您通常需要對較小的二進製文件塊執行許多附加操作才能創建更大的二進製文件。然而,在 Erlang 和 Elixir 中,連接二進製文件會將連接的二進製文件複製到一個新的二進製文件中。

def email(username, domain) do
  username <> "@" <> domain
end

在此函數中,創建電子郵件地址將複製 usernamedomain 二進製文件。現在假設您想在另一個二進製文件中使用生成的電子郵件:

def welcome_message(name, username, domain) do
  "Welcome #{name}, your email is: #{email(username, domain)}"
end

IO.puts(welcome_message("Meg", "meg", "example.com"))
#=> "Welcome Meg, your email is: meg@example.com"

每次連接二進製文件或使用插值 (#{}) 時,您都在製作這些二進製文件的副本。但是,在許多情況下,您在創建它時不需要完整的二進製文件,而隻是在最後打印出來或將其發送到某個地方。在這種情況下,您可以通過創建 IO 數據來構建二進製文件:

def email(username, domain) do
  [username, ?@, domain]
end

def welcome_message(name, username, domain) do
  ["Welcome ", name, ", your email is: ", email(username, domain)]
end

IO.puts(welcome_message("Meg", "meg", "example.com"))
#=> "Welcome Meg, your email is: meg@example.com"

構建 IO 數據比連接二進製文件更便宜。連接多條 IO 數據隻是意味著將它們放在一個列表中,因為 IO 數據可以任意嵌套,這是一種廉價而高效的操作。大多數基於 IO 的 API,例如 :gen_tcp IO ,接收 IO 數據並直接將其寫入套接字,而不將其轉換為二進製。

IO 數據的一個缺點是您不能像使用二進製文件那樣對 IO 數據的第一部分進行模式匹配之類的操作,因為您通常不知道 IO 數據的形狀。在這些情況下,您可能需要通過調用 iodata_to_binary/1 將其轉換為二進製文件,這相當有效,因為它是在 C 中本地實現的。其他函數,例如計算 IO 數據的長度,可以通過調用直接在 iodata 上計算 iodata_length/1

字符數據

Erlang 和 Elixir 也有 chardata/0 的想法。 Chardata 與 IO 數據非常相似:唯一的區別是 IO 數據中的整數表示字節,而 chardata 中的整數表示 Unicode 代碼點。字節 ( byte/0 ) 是 0..255 範圍內的整數,而 Unicode 代碼點 ( char/0 ) 是 0..0x10FFFF 範圍內的整數。 IO 模塊為 chardata 提供 chardata_to_string/1 函數,作為 IO 數據的 iodata_to_binary/1 函數的 "counter-part"。

如果您嘗試在 chardata 上使用 iodata_to_binary/1 ,則會導致參數錯誤。例如,讓我們嘗試在 IO 數據中放置一個無法用一個字節表示的代碼點,例如

IO.iodata_to_binary(["The symbol for pi is: ", ?π])
#=> ** (ArgumentError) argument error

如果我們改用 chardata,它將按預期工作:

iex> IO.chardata_to_string(["The symbol for pi is: ", ?π])
"The symbol for pi is: π"

相關用法


注:本文由純淨天空篩選整理自elixir-lang.org大神的英文原創作品 IO。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。