Erlang函数,带参数编号

时间:2013-01-19 23:28:15

标签: erlang

嗨,我正在通过Fred Hebert学习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).

VS

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

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

所以问题是:

  1. 为什么传递这些sword(#)talk函数不同。
  2. 为什么sword(#)有一个数字作为参数?
  3. 为什么sword(#)似乎有一个arity为1(我将数字参数作为参数计算)?
  4. The chapter of the book I'm at.

    感谢您的时间。

2 个答案:

答案 0 :(得分:1)

  1. 如果查看black_knight函数is_function(Attack, 0)的guard语句,只有传入的函数接受0参数时才会匹配定义。由于talk需要0个参数,因此可以直接传入。 sword接受一个参数,因此您需要将其包装在一个带有0个参数的匿名函数中,然后才能将其传入。
  2. 每个子句定义中的数字是模式匹配的示例。如果以sword为参数调用1,则将执行sword(1) ->子句中的代码。如果传入2作为参数,则将执行sword(2) ->子句。有关更完整的说明,请参阅“了解一些Erlang”中的this section
  3. sword确实有一个arity为1,因此您正确计算参数。

答案 1 :(得分:1)

sword函数的目的是展示可抛出的各种错误。它接受一个参数,因此它可以有多个子句。弗雷德可能选择了整数,因为它们很短,但这并不重要。 sword函数确实有一个arity。

black_knight/1函数应该向您展示如何捕获Erlang中存在的不同错误类。它通过调用传递给它的零arity 函数并为它可能引发的不同错误提供不同的响应来实现此目的。

使用匿名函数将

sword/1传递到black_knight/1 因为 black_knight/1只接受arity零的功能。 由

创建的匿名函数
fun () -> sword(1) end

是arity为零的函数,用一个参数调用sword/1

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