【发布时间】:2012-11-22 08:12:29
【问题描述】:
从 Erlang 编译器的角度来看,下划线变量和以下划线开头的命名变量之间的确切区别是什么(除了增加代码的可读性)?
例如_ 和_Var 不同吗?
【问题讨论】:
从 Erlang 编译器的角度来看,下划线变量和以下划线开头的命名变量之间的确切区别是什么(除了增加代码的可读性)?
例如_ 和_Var 不同吗?
【问题讨论】:
不关心变量_是一个非常特殊变量,它匹配任何东西并且从不绑定到一个值。当我知道那里有东西但我不在乎价值是什么并且我永远不会使用时使用它。看到 _ 永远不会被绑定,它不能在表达式中使用,编译器会将其标记为错误。
像_Var 这样的变量是完全正常的变量,您可以匹配它们并且将绑定到值,这意味着它们可以在表达式中使用。用_ 为变量添加前缀是关于intent。编译器通常会警告您有关模式中绑定但从未使用过的变量,这通常是错误的迹象。但是编译器不会警告以_ 为前缀的变量,例如_Var。目的是我想给变量一个名字,命名是好的,但我知道我永远不会使用它。
请记住,_ 确实是唯一的特殊变量,而_Var 是普通变量,如果使用,它们的行为也是如此。如果你觉得反常,那么你可以在所有变量前加上_,一切仍然有效。
【讨论】:
让我们在这里引用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,所以这里的条件不成立。
【讨论】: