问题 什么是开始...在Erlang用于结束?


我只是踩了一脚 begin...end 在Erlang的文档中(这里),但它没有给出一些如何有用的例子。

在StackOverflow中查看我发现了两个人们将要使用的案例 begin...end,在列表理解中:

但我想知道是否有更多此类用途。

任何人都可以提供另一种方案 begin...end 在Erlang中有用吗?

谢谢


11850
2017-11-21 15:39


起源

您可以使用它来创建快速代码来评估和创建您想要的值。例如 T = {1,2,begin 1+2 end}. 将评估 T={1,2,3} - Muzaaya Joshua
@MuzaayaJoshua但是你的例子甚至没有开始结束。任何人都可以提供一个实际需要使用结束的例子吗?或者他们喜欢大括号? - Aus
@Aus检查下面的答案,有一些例子,没有开始...结束无法完成 - MondKin


答案:


宏,例如:

-define(M(A, B),
    begin
        C = foo(),
        bar(A, B, C)
    end).

6
2017-11-21 19:50



谢谢@P_A。一些澄清,以便其他人不必测试我刚刚测试的内容。可以不使用具有多个表达式的宏 begin...end。但是,如果你在一个只需要一个元素的地方使用那个宏(比如 io:format) 然后 begin...end 是要走的路。 - MondKin
这怎么比-define(M(A,B),bar(A,B,foo())更好。 ? - Lyn Headley
这只是一个展示方式的例子 begin...end 可以使用 - P_A


评估一个catch(总是同一个想法让多个表达式减少到一个)

Res = (catch
    begin
        C = foo(Bar),
        io:format("evaluation of C ok~n"),
        D = bar(A, B, C)
     end),

6
2017-11-21 21:01





正如之前的回答者所提到的,只要你需要多个表达式但只允许一个表达式,就会使用这个结构。

但是,大多数此类案件将被视为一种臭味。我只能记住一些需要单个表达式的地方:函数调用中的参数, catch 表达, case oftry of 列表理解。除了列表理解之外,所有这些都不应该使用 begin end 构造因为变量泄漏到外部范围可能导致后续绑定变为匹配。

列表推导表达式是不同的,因为它被转换为具有自己的范围的单独函数,并且没有引入变量 begin end 泄漏到外部范围。


3
2017-11-21 21:42



在哪一部分 try of ?在a的3个部分中的每个部分 try...of...catch 我们可以提出几条指示。 - MondKin
嗯,你是对的。我以为只允许一个表达式 try <here> of ... catch ... end 表达。实际上这很好用: try a = b, b of A -> A catch C:E -> {C,E} end.。谢谢! - Dmitry Belyaev
@DmitryBelyaev你并非完全错误。 - Aus
@Aus错了什么?答案提出了唯一有效的用法 begin end在列表理解中。并作为 try of 允许多个表达式 begin end 即使您不关心代码的质量,它的应用程序也会减少。 - Dmitry Belyaev
@DmitryBelyaev在你的回答中你写的“案例”只需要一个表达式,而MondKin说它没有。 “case of”将多个true / false条件作为单个表达式,但是您不能在true / false条件之前运行赋值语句,请参阅下面的答案。我想说的是你是正确的,但“表达”的定义并不是那么清楚。 - Aus


根据erlang文档,它是块表达式,它计算每个表达式但只返回最后一个表达式。

请参阅此示例(不使用块表达式):

A = 1,
case A + 1 of
    3 ->
        ok;
    _->
        nop
end.

% returns ok

现在,您可以使用块表达式在case参数中定义A:

case begin A = 1, A + 1 end of
    3 ->
        ok;
    _->
        nop
end.

%returns ok

评估A = 1,然后返回A + 1的结果。

现在我们知道这不起作用:

case A = 1, A + 1 of
    3 ->
        ok;
    _->
        nop
end.

% returns syntax error before: ','

0
2017-10-04 08:57