Elixir 什么';这是错误的:如果是真的,数字是1吗

Elixir 什么';这是错误的:如果是真的,数字是1吗,elixir,Elixir,为什么第二个表单被解析为2个参数被传递给is_number is_number if true, do: 1 true is_number if true do 1 end ** (CompileError) iex:42: undefined function is_number/2 我们可以使用来查看如何在Elixir中解析表达式 iex(6)> IO.puts Macro.to_string(quote do: (is_number if true, do: 1)) is_num

为什么第二个表单被解析为2个参数被传递给is_number

is_number if true, do: 1
true

is_number if true do 1 end
** (CompileError) iex:42: undefined function is_number/2
我们可以使用来查看如何在Elixir中解析表达式

iex(6)> IO.puts Macro.to_string(quote do: (is_number if true, do: 1))
is_number(if(true) do
  1
end)
:ok
iex(7)> IO.puts Macro.to_string(quote do: (is_number if true do 1 end))
is_number(if(true)) do
  1
end
:ok
因此,在第一种情况下,
do
被解析为
if
的一个参数,整个过程被传递给
的是_number
。在第二个参数中,
do
具有不同的优先级,并最终绑定到
is_number
调用自身作为第二个参数,因此我们最终调用
if/1
is_number/2
,这是毫无意义的

至于原因,通常使用
do
将完整表达式捕获为语句,如

if something_really_complicated arg1, arg2, arg3 do
  # ...
end
因此,在这种情况下,尽可能松散地绑定
do
是有意义的。相反,如果我们尝试将
do:
作为带有显式逗号的关键字参数传递,那么它就像其他任何参数一样,只是一个参数,因此它遵循通常的参数传递规则,而不是特殊的规则


在像Elixir这样的语言中,需要记住的关键是,许多在其他语言中是关键字的东西实际上不在Elixir中
if
语句的解析方式与宏的解析方式完全相同,您可以轻松编写自己的
if
宏,
do:
实际上只是一个关键字参数,附加了一些语法,而不是任何特定的控制语句。这是Elixir(和公司)在特定领域任务中表现出色的一个重要原因。

我不熟悉Ruby,它们是否真的像您的示例中那样有带参数的if语句?我浏览了一些教程,但没有看到。所以,为了让我的头脑中明白这一点,长生不老药基本上会通过任何一种方法。。。它的最外层函数的end子句。简单地说是这样吗?如果我不清楚的话,很抱歉。在Ruby中,
if
实际上是一个特殊的关键字。我说的是关于
do
语义的长生不老药。我已经删掉了对Ruby的引用,因为这对我回答的实质内容来说并不是必需的。但在长生不老药中,你是正确的<代码>执行。。end只需进入一个名为
do:
的关键字参数,并传递给最外层的函数。事实上,我刚刚测试了它,
如果
也是Elixir中的宏;它编译成
case
(这是一个关键字)。我很难理解为什么
do
绑定到
is\u number(如果(true))
。括号在这一点上没有用吗?我们用括号调用
is_number
,括号应该明确地告诉编译器参数是什么。参数是
if(true)
,这是胡说八道。当
do
不在括号内时,为什么它会“put”到同一个参数列表中,这是非常不直观的。