理解 Elixir 中的 List.to_string
Source: Dev.to
list = [1, 2, 3]
IO.puts "list is ", list上述代码 不会 工作 —— IO.puts/2 的第二个参数需要二进制(字符串)。尝试其他变体,例如 IO.inspect list,只会打印出列表本身。
为什么 List.to_string/1 并非你所期待的那样
Elixir 确实有一个名为 List.to_string/1 的函数,但它 不会 将列表转换为可打印的列表表示。相反,它把列表视为 Unicode 码点的集合,并据此构建一个 UTF‑8 二进制。
iex> [232, 137, 178] |> List.to_string()
>
iex> [1, 2, 3] |> List.to_string()
>结果是一个 bitstring(二进制),表示给定码点的 UTF‑8 编码。当二进制中包含不可打印字符时,IEx 会使用 > 语法显示它。
检查结果
iex> [232, 137, 178] |> List.to_string() |> i
Term
>
Data type
BitString
Byte size
6
Description
This is a string: a UTF‑8 encoded binary. It's printed with the `>`
syntax because it contains non‑printable UTF‑8 encoded code points.
Implemented protocols
Collectable, IEx.Info, Inspect, JSON.Encoder, List.Chars, String.Chars一个 BitString(或二进制)仅仅是一串字节。在这里它是一个 UTF‑8 编码的字符串,而不是原始列表的文本表示。
List.to_string/1 实际上做了什么
该函数会将列表扁平化,将每个元素解释为 Unicode 码点,并构建二进制:
iex> ["o","m",["z","y"]] |> List.to_string()
"omzy"打印该二进制会显示连接后的字符:
iex> ["o","m",["z","y"]] |> List.to_string() |> IO.puts()
omzy
:ok如果你提供一个由对应列表文本表示字符的 ASCII 码组成的列表,就可以得到该表示的字符串:
iex> [91, 50, 51, 50, 44, 32, 49, 51, 55, 44, 32, 49, 55, 56, 93]
|> List.to_string()
|> IO.puts()
[232, 137, 178]
:ok正确的列表打印方式
如果你想要一个人类可读的列表表示(类似于 IO.inspect/1 的输出),请使用 inspect/1:
iex> [232, 137, 178] |> inspect() |> IO.puts()
[232, 137, 178]
:ok
iex> ["o","m",["z","y"]] |> inspect() |> IO.puts()
["o", "m", ["z", "y"]]
:okinspect/1 返回一个字符串,显示列表的形式正好与在 Elixir 源码中出现的形式相同。
小结
List.to_string/1将整数(码点)列表转换为 UTF‑8 二进制,而不是列表的文本表示。- 得到的二进制是一个 BitString,如果其中包含不可打印字符,可能会以
>方式显示。 - 若需获取列表的可打印表示,请使用
inspect/1(或直接使用IO.inspect/1)。