当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


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。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。