我正在深入了解Phoenix如何将模板呈现为iodata,我发现一些对我来说很奇怪的列表。我似乎错过了涉及"垂直条"的列表的基本语法。或"垂直管道"字符(|
)。
以下是我做了解的一些例子:
# prepends 1 to the list [2, 3]
l = [1 | [2, 3]] #=> [1, 2, 3]
# matches the head and tail into variables
inspect_tail = fn ([_head | tail]) -> IO.inspect(tail) end
我得到的。但这是什么?
l = ["hi" | "there"] #=> ["hi" | "there"]
它似乎是一个头尾的列表:
is_list(["hi" | "there"]) #=> true
hd(["hi" | "there"]) #=> "hi"
tl(["hi" | "there"]) #=> "there"
...但如果给出这样的列表,length(list)
函数会给ArgumentError
。
它是什么,它用于什么?
答案 0 :(得分:6)
不正确的清单是正确的。
我将引用Learn You Some Erlang中的一个注释,它总结得很好。
注意:使用
[1 | 2]
形式提供了我们称之为“不正确的列表”。当您以[Head|Tail]
方式模式匹配时,不正确的列表将起作用,但将无法与Erlang的标准函数(甚至长度())一起使用。这是因为Erlang期望正确的列表。正确的列表以空列表作为最后一个单元格结束。在声明[2]
之类的项目时,列表会以适当的方式自动形成。因此,[1|[2]]
会起作用!不正确的列表虽然在语法上有效,但在用户定义的数据结构之外的使用非常有限。
答案 1 :(得分:3)
它确实是一个不正确的列表,所谓的因为,与正确的列表不同,它有一个head元素和一个尾部本身就是一个列表,一个不正确的列表以非列表结尾,因为最后一个元素是既不是利弊也不是零。 (由cons cell / nil verbiage困惑?见结束。)
您可以查看the inspect tests for an improper list here以查看其实际效果。
你会发现使用它的功能正常,like hd/1
,的参数类型规格为maybe_improper_list
,而其他人like length/1
,只需要一个正确的列表。
如果你没有Lisp背景,那个cons cell / nil位可能会令人困惑。
“Nil”基本上是“空列表”,但我发现调用它会导致列表的循环定义:“列表是一个与尾部相关联的头元素,它本身就是一个列表,或者它是空列表“导致”Gee,我从来没有猜到一个空列表是一个列表!感谢你启发我!:rolleyes:“
通过区分nil作为它自己的特殊事物,我们可以说,“Nil是一个列表,你可以通过将一个元素放到列表中来构建另一个列表。”那是一个不错的归纳数据类型定义。 :)