2015-09-27 70 views
26

新建药剂从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 

我在做什么错了?药剂类似于Ruby,但它具有不同的行为....

+4

这是一个很大的错误,因为Elixir看起来像Ruby,它也会像Ruby一样行事。 –

回答

59

您应该使用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 

为了解释这种现象,我们需要了解字符串药剂是如何工作的。有两种字符串。二进制字符串(双引号)和字符列表(单引号)。在内部,这些是从更简单的基元构建的。二进制字符串从二进制文件建立和字符列表,从列表中建:

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看到一个只有整数的列表时,为了方便起见,它试图将它打印为一个字符串。但是,它仍然只是一个整数列表。

在上述示例,9798代表用于字符ab Unicode码点,以便它们将被显示为字符串,即使使用IO.inspect

现在你可以看到为什么它印在你的例子^A^B - 这些只是control characters from the ASCII encoding,碰巧由码点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' 

如果你打开iex并键入h Inspect.Opts,你会看到,药剂做到这一点有其他价值的东西,特别是结构和二进制文件。

+0

@ patrick-oscity很好的答案..真正清除了事情的实施方式。 但是我想问一下,为什么没有内置的字符串类型..他们是要实现它还是它伸出长生不老的方式......? – VoidZero

+1

@VoidZero它深藏在erlang虚拟机内部,所以它不会改变。也就是说,二进制字符串工作得很好,所以基本上不需要不同的东西。 –