为什么 for x <- 3..4, do: x * 3 return '\t\f' 在 Elixir 中?

Why does for x <- 3..4, do: x * 3 return '\t\f' in Elixir?

在 Elixir 中,为什么理解 for x <- 3..4, do: x * 2 导致 [6, 8]for x <- 3..4, do: x * 3 导致 '\t\f'

我正在 iex repl.

中执行此操作

这是 Elixir 中最令人困惑的陷阱之一:字符列表的“人性化”。有关围绕同一问题的问题,请参阅 this post

Charlists 是整数代码点的列表,用于表示未编码的字符串(在编码被引入之前的日子里在旧的 Erlang 库中更常见)。因此,如果您有一个整数列表,Elixir(出于历史原因)必须猜测您是否打算表示一个 'string' —— 因此如果该列表中的所有整数都低于 127,Elixir 会假设这必须是代表 'string' 数据的字符列表,它会打印出相应的 ASCII 字符以生成可读字符串。

您可以通过在对 IO.inspect/2:

的调用中设置 charlists: :as_lists 选项来显示实际的内部表示
iex(1)> result = for x <- 3..4, do: x * 3
'\t\f'
iex(2)> IO.inspect(result, charlists: :as_lists)
[9, 12]
'\t\f'

或更简单地说:

iex> IO.inspect([9, 12], charlists: :as_lists)
[9, 12]
'\t\f'

这向我们展示了预期的整数 (9, 12),如果我们费心在 Unicode 或 ASCII 代码图表中查找这些,我们会看到 \t\f 字符分别由代码点 9 和 12 表示。

请记住,这些数据表示只是视觉上的——基础数据 100% 相同:

iex> [9, 12] === '\t\f'
true