我刚刚开始使用 Elixir。我正在使用 ExUnit 为我自己实现的简单 Enumerable 函数编写一些测试,而不使用标准 Enum 模块。
在我的测试中,我发现每当我引用列表
[7, 8, 9]
时,一旦将其打印在标准输出中,我就会看到字符列表~c"\a\b\t"
。为什么会发生这样的事情?
Elixir 有两种字符串:二进制(双引号)和字符列表(使用 ~c sigil 构建,或单引号)。字符列表继承自 Erlang,内部表示为整数列表,映射到字符串的代码点。 当您使用
inspect
和 IO.inspect
等函数时,Elixir 会尝试智能地将整数列表格式化为字符串以方便阅读。但是,在某些情况下,您最终会得到一个无意义的字符串,因为列表中的所有整数恰好都是有效的代码点。例如,字符 A 到 Z 在 ASCII 中表示为整数 65 到 90。
iex> IO.inspect [65, 66, 67]
~c"ABC"
如果您想打印原始列表,可以使用
charlists: :as_lists
选项。要查看完整的选项列表,请启动 iex
并输入 h Inspect.Opts
。
iex> IO.inspect [65, 66, 67], charlists: :as_lists
[65, 66, 67]
与 Elixir < 1.4, you can use
char_lists: false
。
顺便说一句,这并不是 Elixir 向您隐藏底层构建块的唯一情况,二进制文件(双引号字符串)和结构也会发生这种情况。
更深层的原因是 Elixir 和 Erlang 没有用户定义的类型,因此无法区分列表和单引号字符串,因为两者都只是列表。然而,这在其他情况下也可能是一种优势。例如,它允许我们轻松地序列化 Elixir 和 Erlang 中的任何数据结构,因为它只能从该语言附带的基本构建块构建。
虽然@Patrick的答案是绝对正确的,但您还可以将
IEx
配置为始终将charlists
显示为常规列表,而不是每次都手动调用inspect
:
iex> IEx.configure(inspect: [charlists: :as_lists])
# => :ok
iex> [65, 66, 67]
# => [65, 66, 67]
iex> 'ABC'
# => [65, 66, 67]
这是支持选项的完整列表。
您还可以将此行放在主路径中的
~/.iex.exs
中,以便该配置应用于系统上的每个 IEx 会话。