2

嗨,我正在通过 Fred Hebert 的 Learn You Some Erlang 学习 Erlang。

而且我遇到了一个令我感到困惑的代码:

sword(1) -> throw(slice);
sword(2) -> erlang:error(cut_arm);
sword(3) -> exit(cut_leg);
sword(4) -> throw(punch);
sword(5) -> exit(cross_bridge).

talk() -> "blah blah".

black_knight(Attack) when is_function(Attack, 0) ->
    try Attack() of
        _ -> "None shall pass."
    catch
        throw:slice -> "It is but a scratch.";
        error:cut_arm -> "I've had worse.";
        exit:cut_leg -> "Come on you pansy!";
        _:_ -> "Just a flesh wound."
    end.

所以这就是混乱。我不明白sword(#)功能。为什么有数字作为参数?该函数is_function实际上检查这些函数是否是 arity 0 并且显然所有sword(#)函数都是 arity 0。

与函数相比,将函数传递sword(#)black_knight函数的方式也不同talk

下面是这本书如何传递一个sword函数和talk函数。

exceptions:black_knight(fun exceptions:talk/0).

对比

exceptions:black_knight(fun() -> exceptions:sword(1) end).

我们talk只传递函数作为sword(1)函数,我们必须用匿名函数包装它。我不明白。

所以问题是:

  1. 为什么传递这些sword(#)talk函数不同。
  2. 为什么sword(#)有一个数字作为参数?
  3. 为什么sword(#)当它的 arity 看起来像 1 时有 0 arity(我将 number 参数作为参数计算)?

我在的书的章节。

感谢您的时间。

4

2 回答 2

1
  1. 如果您查看函数的保护语句black_knightis_function(Attack, 0)则仅当传入的函数接受 0 个参数时,它才会匹配定义。由于talk带0个参数,所以可以直接传入。 sword接受一个参数,因此您需要将其包装在一个接受 0 个参数的匿名函数中,然后才能将其传入。
  2. 每个子句定义中的数字是模式匹配的一个例子。如果您调用swordwith1作为参数,您将执行子句中的代码sword(1) ->。如果您2作为参数传入,您将执行该子句sword(2) ->。有关更完整的描述,请参阅Learn You Some Erlang 中的这一部分。
  3. sword确实有一个 1,所以你正确地计算了参数。
于 2013-01-20T01:35:17.737 回答
1

sword函数的目的是展示可以抛出的不同类型的错误。它接受一个参数,因此它可以有多个子句。Fred 可能选择整数是因为它们很短,但这并不重要。该sword函数的数量确实为 1。

black_knight/1函数应该向您展示如何捕获 Erlang 中存在的不同错误类。它通过调用传递给它的参数函数并为它可能抛出的不同错误提供不同的响应来做到这一点。

sword/1被传入black_knight/1使用匿名函数 ,因为 black_knight/1只接受零元的函数。创建的匿名函数

fun () -> sword(1) end

是用一个参数调用的零元sword/1函数。

talk/0可以直接传递,因为它已经是一个零参数函数。

于 2013-01-20T01:37:50.907 回答