16

从 Erlang 编译器的角度来看,下划线变量和以下划线开头的命名变量之间的确切区别是什么(除了增加代码的可读性)?

例如是__Var不同的?

4

2 回答 2

25

don't care变量_是一个非常特殊的变量,它匹配任何东西并且从不绑定到一个值。当我知道那里有东西但我不在乎价值是什么并且我永远不会使用时使用它。Seeing_永远不会被绑定,它不能在表达式中使用,编译器会将其标记为错误。

像这样的变量_Var是完全正常的变量,您可以匹配它们并将绑定到值,这意味着它们可以在表达式中使用。为变量加上前缀_是关于intent的。编译器通常会警告您有关模式中绑定但从未使用过的变量,这通常是错误的标志。但是编译器不会对以_like in为前缀的变量发出警告_Var。目的是我想给变量一个名字,命名是好的,但我知道我永远不会使用它。

请记住,这_实际上是唯一的特殊变量,并且_Var是普通变量,如果使用的话,它们的行为也是如此。如果您感到反常,那么您可以在所有变量前加上前缀_,一切仍然有效。

于 2012-12-05T12:10:50.747 回答
20

让我们在这里引用文档

匿名变量用下划线 ( _) 表示,可以在需要变量但可以忽略其值时使用。[...]

_例如,以下划线 () 开头_Height的变量是普通变量,而不是匿名变量:但是编译器会忽略它们,因为它们不会为未使用的变量生成任何警告

换句话说,_Var当您需要匹配匹配的表达式时使用表单 - 但不想进一步使用它 AND/OR 您想显示其含义。_当你和编译器都不应该关心将被它匹配的表达式时,你使用变量。

示例 1:

member(_, []) -> [].

在这个函数中不是很清楚第一个_匹配什么。但是直接重写,像这样:

member(Elem, []) -> [].

... 如果代码是用warn_unused_vars设置的标志编译的,将产生一个警告。但是,您仍然可以通过使用下划线变量使您的代码在此处可读:

member(_Elem, []) -> [].

示例 2:

{_, _, Some} = {1, 2, 3}

这个元组匹配会很顺利,因为元组的前两个元素将被完全忽略。

{_Var, _Var, Some} = {1, 2, 3}

但是,这种匹配会失败:虽然_Var不必使用,但应该用相同的值“填充”!因为 1 不等于 2,所以这里的条件不成立。

于 2012-12-04T16:31:12.647 回答