来自Ruby的Elixir新手,我尝试使用以下代码打印出地图的数组值:
地图script.ex
list = [0, 1]
map = %{0 => [1, 2], 1 => [2, 3]}
Enum.each list, fn n ->
IO.puts map[n]
end
输出:
^A^B
^B^C
我做错了什么? Elixir看起来类似于Ruby,但它的行为却不同......
答案 0 :(得分:63)
您应该使用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
但是,您可能仍会遇到一些特殊值的问题:
iex> IO.inspect [97, 98]
'ab' # prints "'ab'"
'ab' # return value of IO.inspect
为了解释这种行为,我们需要了解字符串在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'
起初可能看起来很混乱,但这是由于两件事而发生的。首先,没有内置字符串类型,因为我们已经看到字符串是从其他基本类型构建的。其次,Elixir中没有用户定义的类型。因此,当Elixir看到只有整数的列表时,它会尝试将其打印为字符串以方便使用。然而,在引擎盖下它仍然只是一个整数列表。
在上面的示例中,97
和98
代表字符a
和b
的unicode代码点,因此这些代码点将显示为字符串,即使使用IO.inspect
。
现在,您可以看到在示例中打印^A^B
的原因 - 这些只是control characters from the ASCII encoding,恰好由代码点1
和2
表示。
但是,您可以传递选项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'
如果您打开iex
并输入h Inspect.Opts
,您会看到Elixir也会使用其他值进行此类操作,特别是结构和二进制文件。