警卫条款
Guard 子句使我们能够在执行函数之前检查参数。由于可读性,guard 子句通常比 if
和 cond
更受欢迎,并且使编译器更容易使某种优化技术更容易。执行所有防护匹配的第一个函数定义。
以下是使用保护和模式匹配的阶乘函数的示例实现。
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
本身并不是一个错误。如某些其他语言中常见的那样,返回 -1
或 0
或其他一些错误值会隐藏你调用未定义函数的事实,隐藏错误的来源,可能会为未来的开发人员创建一个巨大的痛苦错误。