2015-05-04 50 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 –