Ответ 1
Макросы, например:
-define(M(A, B),
begin
C = foo(),
bar(A, B, C)
end).
Я просто топал в begin...end
в документации Erlang (здесь), но он не дает некоторых примеров того, как это полезно.
Глядя сюда в StackOverflow, я обнаружил два случая, когда люди использовали бы begin...end
, как в понимании списка:
Но интересно, больше ли таких применений.
Может ли кто-нибудь предоставить другой сценарий, в котором a begin...end
полезен в Erlang?
Спасибо
Макросы, например:
-define(M(A, B),
begin
C = foo(),
bar(A, B, C)
end).
Чтобы оценить улов (всегда одна и та же идея иметь несколько выражений, сведенных к одному)
Res = (catch
begin
C = foo(Bar),
io:format("evaluation of C ok~n"),
D = bar(A, B, C)
end),
Как отмечали предыдущие ответчики, эта конструкция используется всякий раз, когда вам нужно иметь несколько выражений, но разрешено только одно.
Однако большинство таких случаев считалось бы вонючим стилем. Я помню только несколько мест, где ожидается одно выражение: аргумент в вызове функции, выражение catch
, case of
, try of
и понимание списка. Все они, за исключением понимания списка, не должны использоваться с конструкцией begin end
, потому что переменные просачиваются во внешнюю область видимости, что приводит к тому, что последующие привязки становятся совпадениями.
Выражение для выражения списка различно, потому что оно преобразуется в отдельную функцию со своей собственной областью, и никакая переменная, введенная в begin end
, не протекает во внешнюю область.
Согласно документации erlang это блочное выражение, которое оценивает каждое выражение, но возвращает только последний.
См. этот пример (не используя выражение блока):
A = 1,
case A + 1 of
3 ->
ok;
_->
nop
end.
% returns ok
Теперь вы можете определить A в аргументе case, используя выражение блока:
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: ','