警卫条款

Guard 子句使我们能够在执行函数之前检查参数。由于可读性,guard 子句通常比 ifcond 更受欢迎,并且使编译器更容易使某种优化技术更容易。执行所有防护匹配的第一个函数定义。

以下是使用保护和模式匹配的阶乘函数的示例实现。

defmodule Math do
    def factorial(0), do: 1
    def factorial(n) when n > 0: do: n * factorial(n - 1)
end

第一个模式匹配 if(且仅当)参数是 0。如果参数不是 0,则模式匹配失败,并检查下面的下一个函数。

第二个函数定义有一个保护条款:when n > 0。这意味着只有当参数 n 大于 0 时,此函数才匹配。毕竟,没有为负整数定义数学因子函数。

如果函数定义(包括它们的模式匹配和保护子句)都不匹配,则会引发 FunctionClauseError。当我们传递一个负数作为参数时,会发生这种情况,因为它没有为负数定义。

请注意,这个 FunctionClauseError 本身并不是一个错误。如某些其他语言中常见的那样,返回 -10 或其他一些错误值会隐藏你调用未定义函数的事实,隐藏错误的来源,可能会为未来的开发人员创建一个巨大的痛苦错误。