2015-09-27 71 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虛擬機內部,所以它不會改變。也就是說,二進制字符串工作得很好,所以基本上不需要不同的東西。 –