随附以下编译器例外:
/basho/riak/deps/bitcask/src/bitcask_fileops.erl:855: variable 'Result' unsafe in 'try' (line 843)
ERROR: compile failed while processing /basho/riak/deps/bitcask: rebar_abort
make: *** [compile] Error 1
但是,如果我重命名了变量名的首次使用
Result
to
Res
list_dir(Directory, Retries) when is_integer(Retries), Retries > 0 ->
Port = get_efile_port(),
try erlang:port_info(Port) of
Res ->
error_logger:info_msg("list_dir - erlang:port_info(~p) -> ~p ", [Port,Res])
catch
_:Reason ->
error_logger:info_msg("list_dir - erlang:port_info(~p) -> {error, ~p }",[Port,Reason])
end,
case prim_file:list_dir(Port, Directory) of
{error, einval} ->
error_logger:info_msg(" list_dir - port : ~p , directory : ~p", [Port, Directory]),
clear_efile_port(),
list_dir(Directory, Retries-1);
Result ->
Result
end.
据我所知,变量在两个不同的范围内(尝试/捕获和案例)。这是一个编译器错误,或者我未能正确理解Erlang语法吗?
这不是编译器错误。问题在于,在第一个示例中,您在两个地方使用
Result
:第一个在try
case
Result
将绑定到
erlang:port_info(Port)
呼叫的结果,但是如果该调用会引起例外,则不会绑定。这意味着它在
Result
中的使用将是模棱两可的,因为在第二个条款中,如果它已经绑定,则将匹配或绑定到
case
如果尚未绑定的结果。尝试块本身返回一个值。因此,您可以避免这样的情况
case
Etc.
,例如,这是我现在正在从事的项目中的几行:
prim_file:list_dir(Port, Directory)
如果我试图在“尝试”内部分配“ F”,我会遇到您遇到的同样的错误!
list_dir(Directory, Retries) when is_integer(Retries), Retries > 0 ->
Port = get_efile_port(),
Result = try erlang:port_info(Port) of
...
子句匹配,结果必定会有价值。它的范围不受阻碍的限制。考虑以下代码:
F = try
python:call(P, 'python.repo_admin_cmd', 'repo_admin_cmd', [erlang:list_to_binary(Command) || Command <- Commands])
catch error:{python, _Class, _Argument, _StackTrace} ->
error
end
even仅在
Result
子句中绑定,在外部范围中仍然可以访问。请注意,同一件事也有clive的变量,该变量也在案件子句中也有界限。