下划线变量和命名变量之间的确切区别是什么,从Erlang编译器的角度来看,这些变量以下划线开头(除了为代码添加可读性之外)?
例如_
和_Var
有什么不同?
答案 0 :(得分:23)
不关心变量_
是一个非常特殊变量,它匹配任何内容并且从不绑定到一个值。当我知道那里有东西时使用它,但我不在乎价值是什么,我将永远不会使用。看到_
永远不会绑定它不能在表达式中使用,并且编译器将其标记为错误。
_Var
之类的变量是完全正常的变量,可以与之匹配,并且将绑定到值,这意味着它们可以在表达式中使用。使用_
对变量进行前缀约为 intent 。编译器通常会警告您绑定在模式中但从未使用的变量,通常是错误的标志。但编译器不会像_
中那样警告前缀为_Var
的变量。意图是我想给变量命名,命名的东西很好,但我知道我永远不会使用它。
请记住,_
实际上是唯一的特殊变量,而_Var
是正常变量,如果使用则表现如此。如果你感觉有悖常理,那么你可以用_
为所有变量添加前缀,一切都会有效。
答案 1 :(得分:19)
让我们在这里引用doc:
匿名变量由下划线(
_
)表示,可以使用 当需要变量但其值可以忽略。 [...]以下划线(
_
)开头的变量,例如_Height
,是正常变量,而不是匿名变量:然而,编译器会忽略它们,因为它们不会生成任何警告对于未使用的变量。
换句话说,当您需要匹配匹配的表达式时,您使用_Var
表单 - 但是不想进一步使用它和/或您希望显示其含义。当你和编译器都不应该关心它将匹配的表达式时,你使用_
变量。
示例1:
member(_, []) -> [].
在这个函数中,第一个_
匹配的内容并不十分清楚。但是直接重写它,就像这样:
member(Elem, []) -> [].
如果使用标志warn_unused_vars
设置编译代码,...将生成警告。但是,您仍然可以通过使用下划线变量来使您的代码可读:
member(_Elem, []) -> [].
示例2:
{_, _, Some} = {1, 2, 3}
这个元组匹配将完全正确,因为元组的前两个元素将被完全忽略。
{_Var, _Var, Some} = {1, 2, 3}
然而,这种匹配会失败:虽然_Var
不必使用,但它应该被填充'具有相同的价值!由于1不等于2,因此条件失败。