这个 gen_server.erl 代码的目的是什么?

What's the purpose of this gen_server.erl code?

unregister_name({local,Name}) ->
    _ = (catch unregister(Name));
unregister_name({global,Name}) ->
    _ = global:unregister_name(Name);
unregister_name({via, Mod, Name}) ->
    _ = Mod:unregister_name(Name);
unregister_name(Pid) when is_pid(Pid) ->
    Pid.

本文来自 gen_server.erl。如果 _ 始终匹配并且匹配始终计算为右侧表达式,那么 _ = expression() 行在此处做什么?

在 Erlang 中,函数的最后一个表达式是它的 return 值,所以有人可能会想检查,什么 global:unregister_name/1Mod:unregister_name(Name) return 并尝试模式化匹配。

_ = expression() 没有做任何特别的事情,但提示应该忽略此 return 值(例如,因为它们没有记录并且可能会更改)。但是在最后一个表达式中,Pid 被显式 returned。这意味着,您可以像这样进行模式匹配:

case unregister_name(Something) of
    Pid when is_pid(Pid) -> foo();
    _ -> bar()
end.

总结一下:这些行在那里没有做任何事情,但是当其他人正在阅读源代码时,它们显示了程序员的原始意图。

不幸的是,这个特定的函数没有被导出,并且在原始模块中从未在模式匹配中使用过,所以我没有一个例子来支持它:)

通常 _ = ... 匹配用于在使用其 -Wunmatched_returns 选项时消除有关不匹配函数 return 值的 dialyzer 警告。如文档所述:

-Wunmatched_returns
    Include warnings for function calls which ignore a structured return value or
    do not match against one of many possible return value(s).

通过将 return 值与 _ "don't care" 变量显式匹配,您可以使用这个有用的透析器选项,而不必看到您没有看到 return 值的警告不在乎。

我会注意到我从 come across this:

The Power of Ten – Rules for Developing Safety Critical Code

Gerard J. Holzmann

NASA/JPL Laboratory for Reliable Software Pasadena, CA

91109

[...]

  1. Rule: The return value of non-void functions must be checked by each calling function, and the validity of parameters must be checked inside each function.

    Rationale: This is possibly the most frequently violated rule, and therefore somewhat more suspect as a general rule. In its strictest form, this rule means that even the return value of printf statements and file close statements must be checked. One can make a case, though, that if the response to an error would rightfully be no different than the response to success, there is little point in explicitly checking a return value. This is often the case with calls to printf and close. In cases like these, it can be acceptable to explicitly cast the function return value to (void) – thereby indicating that the programmer explicitly and not accidentally decides to ignore a return value. In more dubious cases, a comment should be present to explain why a return value is irrelevant. In most cases, though, the return value of a function should not be ignored, especially if error return values must be propagated up the function call chain. Standard libraries famously violate this rule with potentially grave consequences. See, for instance, what happens if you accidentally execute strlen(0), or strcat(s1, s2, -1) with the standard C string library – it is not pretty. By keeping the general rule, we make sure that exceptions must be justified, with mechanical checkers flagging violations. Often, it will be easier to comply with the rule than to explain why noncompliance might be acceptable.