Erlang 错误处理,“try”中的 X 不安全

发布于 2024-09-14 12:23:41 字数 340 浏览 5 评论 0原文

谁能告诉我为什么这段代码会说 X 在“try”中不安全,我知道为什么,但更知道如何修复它。

try X = lists:append(lists:zipwith3(fun(X, Y, Z) -> [X, Y, Z] end, Data1, Data2, Data3)) of
            MP -> X
            catch K -> (X = 0)
            end.
            %MP = [lists:zipwith3(X, Y, Z) || X, Y, Z <-  [Data1, Data2, Data3]],


P = X

Can anyone enlighten me as to why this bit of code spits back that the X is unsafe in 'try', well I know why, but more so how to fix it.

try X = lists:append(lists:zipwith3(fun(X, Y, Z) -> [X, Y, Z] end, Data1, Data2, Data3)) of
            MP -> X
            catch K -> (X = 0)
            end.
            %MP = [lists:zipwith3(X, Y, Z) || X, Y, Z <-  [Data1, Data2, Data3]],


P = X

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

山川志 2024-09-21 12:23:41

解决这个问题的最简单方法是将赋值放在 try-catch 之外:

X =
    try lists:append(lists:zipwith3(fun(X, Y, Z) -> [X, Y, Z] end, Data1, Data2, Data3)) of
        MP -> MP
    catch K -> 0
    end.

至于为什么会发生这种情况,Erlang 参考手册中有关表达式的章节 说:

对于 try 表达式,变量范围是有限的,因此表达式中绑定的变量在表达式之外始终“不安全”。

它曾经说过“这有待改进”,但在 此提交

The simplest way to fix it is to put the assignment outside of the try-catch:

X =
    try lists:append(lists:zipwith3(fun(X, Y, Z) -> [X, Y, Z] end, Data1, Data2, Data3)) of
        MP -> MP
    catch K -> 0
    end.

As for why this happens, the chapter on expressions in the Erlang reference manual says:

For the try expression variable scoping is limited so that variables bound in the expression are always 'unsafe' outside the expression.

It used to say "This is to be improved", but that was removed in this commit.

默嘫て 2024-09-21 12:23:41

我认为这是不安全的,因为您没有涵盖所有例外情况。
当你有

catch K -> (X = 0)

我相信它只会捕获抛出的异常时,仍然存在错误并退出。国际研究委员会
所以你可能需要

catch _:K -> (X=0)

或明确地将它们捕获为

catch 
  error:K -> (X=0);
  exit:K -> (X=0);
  throw:K -> (X=0)

(我不是100%我的原子名称是正确的,但想法仍然是一样的)

It is unsafe I believe due to the fact that you do not cover all the exceptions.
When you have

catch K -> (X = 0)

I believe it'll only catch thrown exceptions, there are still errors, and exits. IIRC
so you will probably need

catch _:K -> (X=0)

or explicitly catch them as

catch 
  error:K -> (X=0);
  exit:K -> (X=0);
  throw:K -> (X=0)

(I'm not 100% that I have the atom names correct, but the idea is still the same)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文