Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 解释为字符列表的长生不老药列表_List_Elixir - Fatal编程技术网

List 解释为字符列表的长生不老药列表

List 解释为字符列表的长生不老药列表,list,elixir,List,Elixir,我刚开始用长生不老药。我正在为我自己实现的简单可枚举函数编写一些使用ExUnit的测试,而不使用标准Enum模块 在我的测试中,我发现每当我引用列表[7,8,9],一旦它在stdout中打印出来,我就会看到字符列表'\a\b\t'。为什么会发生这种情况?Elixir有两种字符串:二进制(双引号)和字符列表(单引号)。后一个变量继承自Erlang,在内部表示为整数列表,这些整数映射到字符串的代码点 当您使用诸如inspect和IO.inspect之类的函数时,Elixir会尽量聪明,将整数列表格式

我刚开始用长生不老药。我正在为我自己实现的简单可枚举函数编写一些使用ExUnit的测试,而不使用标准Enum模块


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

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

当您使用诸如
inspect
IO.inspect
之类的函数时,Elixir会尽量聪明,将整数列表格式化为字符串,以便于阅读。然而,在某些情况下,仅仅因为列表中的所有整数恰好都是有效的代码点,就得到了一个无意义的字符串。例如,字符A到Z在ASCII中表示为整数65到90

iex> IO.inspect [65, 66, 67]
'ABC'
如果要打印原始列表,可以使用
charlists::as_lists
选项。要查看选项的完整列表,请启动iex并键入Inspect.Opts

iex> IO.inspect [65, 66, 67], charlists: :as_lists
[65, 66, 67]
使用Elixir<1.4,您可以使用
字符列表:false

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


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

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

iex>iex.configure(检查:[charlists::as\u list])
#=>:好的
iex>[65,66,67]
# => [65, 66, 67]
iex>“ABC”
# => [65, 66, 67]

这里有一个

来为您的环境禁用此行为,以始终应用配置:

# .iex.exs
IEx.configure(inspect: [charlists: :as_lists])
这样就不需要提供
检查
或运行
IEx的选项。每次手动配置


如果要覆盖特定项目的全局设置,也可以使用。

谢谢@Patrick Oscity,这就是我要找的解释。@Patrick Oscity:只是出于好奇,从这个意义上说Elixir没有“用户定义的类型”?如果你真的需要它们,你可以使用@type definally\u string::{:definally\u string,string.t}与Haskell有什么根本的区别吗?@MiroslavPrymek区别在于类型只是Elixir中的注释,而不是语言的“真正”部分。您可以使用它们进行静态分析,但实际类型是动态的,忽略注释。因此,类型可以创建为注释,但在程序运行时无法引用这些类型。例如,不能编写接受任何值并返回其类型的函数。在运行时,所有值似乎都是由基本类型组成的。但是,也可以看到,类型的定义也不那么严格,这可能会让来自Haskell的人感到震惊;-)。我现在真的找不到合适的词语,但我会试试。您可能想阅读Dave Thomas的《编程长生不老药》一书中的第9章“什么是类型?”。本质上,他说,尽管每个值都是由基本类型组成的,但通过定义期望值遵循特定模式的函数,可以获得准类型。例如,二维空间中的坐标可以用一个两元素元组来表示,然后将这些函数分组到模块中,使用于处理类型的所有函数保持在一起。尽管如此,还是没有办法反思这种类型的打字。这一切都发生在概念层面上,而不是建立在语言中严格的类型规则之上。你会发现,这有时会导致奇怪的错误,但我发现这并不像人们一开始想象的那样是一个问题。请努力接受下面的答案。这个答案现在经常被引用,它应该在左边有一个绿色的格子。我认为这不会发生()。