Elixir列表被解释为char列表

Geo*_*ras 45 list elixir

我刚刚开始使用Elixir.我正在使用ExUnit编写一些测试,用于我自己实现的简单的Enumerable函数,而不使用标准的Enum模块.

在我的测试中,我发现每当我引用列表时[7, 8, 9],一旦它在stdout中打印,我就会看到char列表'\a\b\t'.为什么会发生这种事情?

Pat*_*ity 76

Elixir有两种字符串:二进制文件(双引号)和字符列表(单引号).后一种变体继承自Erlang,并在内部表示为整数列表,映射到字符串的代码点.

当您使用类似功能inspectIO.inspect,药剂试图将智能和格式化整数列表为易于读取的字符串.但是,在某些情况下,您最终会得到一个无意义的字符串,因为列表中的所有整数都恰好是有效的代码点.例如,字符A到Z用ASCII表示为整数65到90.

iex> IO.inspect [65, 66, 67]
'ABC'
Run Code Online (Sandbox Code Playgroud)

如果要打印原始列表,可以使用该charlists: :as_lists选项.有关选项的完整列表,请启动iex并键入h Inspect.Opts.

iex> IO.inspect [65, 66, 67], charlists: :as_lists
[65, 66, 67]
Run Code Online (Sandbox Code Playgroud)

使用Elixir <1.4,您可以使用char_lists: false.

顺便说一句,这不是Elixir隐藏你的底层构建块的唯一情况,它也发生在二进制文件(双引号字符串)和结构上.

更深层次的原因是Elixir和Erlang没有用户定义的类型,因此无法区分列表和单个带引号的字符串,因为两者都只是列表.但是,这在其他情况下也可以成为一种优势.例如,它允许我们简单地序列化Elixir和Erlang中的任何数据结构,因为它只能从该语言附带的基本构建块构建.

  • @MiroslavPrymek的区别在于类型只是Elixir中的注释,而不是语言的“真正”部分。您可以使用它们进行静态分析,但是实际类型是动态的,忽略注释。因此,可以将类型创建为批注,但是在程序运行时无法引用这些类型。例如,您不能编写带有任何值并返回其类型的函数。在运行时,所有值似乎仅由基本类型组成。另请参阅http://elixir-lang.org/getting-started/typespecs-and-behaviours.html (2认同)

She*_*yar 9

尽管@Patrick的回答绝对正确,但是您也可以配置IEx为始终显示charlists为常规列表,而不是inspect每次手动调用:

iex> IEx.configure(inspect: [charlists: :as_lists])
# => :ok

iex> [65, 66, 67]
# => [65, 66, 67]

iex> 'ABC'
# => [65, 66, 67]
Run Code Online (Sandbox Code Playgroud)

是支持的选项完整列表