如何在Elixir中打印出地图的数组值?

Non*_*ona 29 elixir

来自Ruby的Elixir新手,我正在尝试使用以下代码打印出地图的数组值:

地图script.ex

list = [0, 1]
map = %{0 => [1, 2], 1 => [2, 3]}

Enum.each list, fn n ->
  IO.puts map[n]
end
Run Code Online (Sandbox Code Playgroud)

输出:

^A^B
^B^C
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?Elixir看起来类似于Ruby,但它的表现不同......

Pat*_*ity 64

您应该使用IO.inspect而不是IO.puts打印值的内部表示:

iex> IO.puts [1, 2]
^A^B                          # prints "^A^B"
:ok                           # return value of IO.puts

iex> IO.inspect [1, 2]
[1, 2]                        # prints "[1, 2]"
[1, 2]                        # return value of IO.inspect
Run Code Online (Sandbox Code Playgroud)

但是,您可能仍会遇到一些特殊值的问题:

iex> IO.inspect [97, 98]
'ab'                          # prints "'ab'"
'ab'                          # return value of IO.inspect
Run Code Online (Sandbox Code Playgroud)

为了解释这种行为,我们需要了解字符串在Elixir中的工作原理.有两种字符串.二进制字符串(双引号)和字符列表(单引号).在内部,这些是由更简单的原语构建的.二进制字符串是从二进制文件构建的,字符列表是从列表构建的:

iex> "ab"                    # a binary string
"ab"

iex> <<97, 98>>              # the same string in binary syntax
"ab"

iex> 'ab'                    # a character list
'ab'

iex> [97, 98]                # the same character list in list syntax
'ab'
Run Code Online (Sandbox Code Playgroud)

起初可能看起来很混乱,但这是由于两件事而发生的.首先,没有内置字符串类型,因为我们已经看到字符串是从其他基本类型构建的.其次,Elixir中没有用户定义的类型.因此,当Elixir看到只有整数的列表时,它会尝试将其打印为字符串以方便使用.然而,在引擎盖下它仍然只是一个整数列表.

在上面的例子中,9798代表用于字符的Unicode码点ab因此这些将即使使用显示为一个字符串,IO.inspect.

现在您可以看到它^A^B在您的示例中打印的原因- 这些只是ASCII编码中的控制字符,恰好由代码点12.

但是,您可以传递该选项char_lists: :as_lists以打印原始列表,而无需尝试进行此类转换:

iex> IO.inspect [97, 98], char_lists: :as_lists
[97, 98]                                         # prints '[97, 98]'
'ab'                                             # Iex still shows the return value as 'ab'
Run Code Online (Sandbox Code Playgroud)

如果你打开iex并输入h Inspect.Opts,你会发现Elixir也会使用其他值来做这种事情,特别是结构和二进制文件.