嗨,我正在通过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)
函数,我们用匿名函数包装它。我不明白。
所以问题是:
sword(#)
与talk
函数不同。sword(#)
有一个数字作为参数?sword(#)
似乎有一个arity为1(我将数字参数作为参数计算)?The chapter of the book I'm at.
感谢您的时间。
答案 0 :(得分:1)
black_knight
函数is_function(Attack, 0)
的guard语句,只有传入的函数接受0参数时才会匹配定义。由于talk需要0个参数,因此可以直接传入。 sword
接受一个参数,因此您需要将其包装在一个带有0个参数的匿名函数中,然后才能将其传入。sword
为参数调用1
,则将执行sword(1) ->
子句中的代码。如果传入2
作为参数,则将执行sword(2) ->
子句。有关更完整的说明,请参阅“了解一些Erlang”中的this section。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函数。