2015-05-04 37 views
30

我剛剛開始與Elixir。我正在使用ExUnit編寫一些測試,用於我自己實現的簡單Enumerable函數,而不使用標準Enum模塊。Elixir列表解釋爲char列表

在我的測試中,我發現每當我引用列表[7, 8, 9]時,一旦它被打印在stdout中,我就會看到char列表'\a\b\t'。爲什麼會發生這種事情?

+0

請儘量_acccepting_下面的答案。這個答案現在經常被引用,它應該在左邊是一個綠色的檢查器。 – mudasobwa

回答

54

Elixir有兩種字符串:二進制(雙引號)和字符列表(單引號)。後一種變體是從Erlang繼承而來的,並在內部表示爲整數列表,映射到字符串的代碼點。

當您使用像inspectIO.inspect這樣的函數時,Elixir試圖變得聰明,並將整數列表格式化爲一個字符串以方便閱讀。但是,在某些情況下,最終會產生一個無意義的字符串,只是因爲列表中的所有整數都是有效的代碼點。例如,字符A到Z在ASCII中被表示爲整數65到90。

iex> IO.inspect [65, 66, 67] 
'ABC' 

如果您想打印一個原始列表,您可以使用charlists: :as_lists選項。有關選項的完整列表,請激活iexh Inspect.Opts

iex> IO.inspect [65, 66, 67], charlists: :as_lists 
[65, 66, 67] 

隨着藥劑< 1.4,你可以使用char_lists: false

順便說一句,這不是唯一的情況下,藥劑師隱藏你的底層構件,它也發生在二進制文件(雙引號字符串)和結構中。

更深層的原因是Elixir和Erlang沒有用戶定義的類型,所以無法區分列表和單引號字符串,因爲它們都只是列表。但是,這在其他情況下也可能是一種優勢。例如,它允許我們輕鬆地序列化Elixir和Erlang中的任何數據結構,因爲它只能從語言附帶的基本構建塊構建而成。

+0

謝謝@Patrick Oscity,這是我正在尋找的解釋。 –

+0

@帕特里克Oscity:只是爲了我的好奇心,在哪個意義上Elixir沒有「有用戶定義的類型」?如果你真的需要它們,你可以使用 @類型句柄字符串:: {:definitely_string,String.t} 是否與例如哈斯克爾? –

+0

@MiroslavPrymek不同之處在於,這些類型只是Elixir中的註釋,而不是語言的「真正」部分。您可以使用它們進行靜態分析,但實際類型是動態的,忽略註釋。因此,可以將類型創建爲註釋,但在程序運行期間無法引用這些類型。例如,您不能編寫一個具有任何值並返回其類型的函數。在運行期間,所有值看起來都是由基本類型組成的。另請參閱http://elixir-lang.org/getting-started/typespecs-and-behaviours.html –