在函数式编程中,可以用模式匹配和函数来控制程序的流程。我们已经学习了借助=运算符进行模式匹配,如果匹配失败,Elixir会抛出错误并停止执行程序。我们还可以在函数中使用模式匹配,从而完成更复杂的控制任务,这就是本节要讨论的内容。
让我们创建一个简单的程序,比较两个数字的大小,并输出大的那一个。如果两个数字相等,则任意输出其中一个。使用具名函数,创建文件number_compare.ex:
这里出现了具有相同名称的多重函数,它们是用defp指令定义的,而且参数的值不一样。现在不用在意这些细节,你只要知道这些函数的参数有不同值就行。在详细讨论代码之前,我们先运行文件试试:
先看greater的函数,它用>=运算符比较两个数字的大小。如果第一个数字大于或等于第二个数字,表达式的值为true;反之,表达式的值为false。我们需要处理这两种可能性,所以又创建了一个辅助函数check。
多重函数check有两个版本,每个版本处理一种比较结果:一个处理true的情况,另一个处理false的情况。这是可行的,因为Elixir的函数参数可以是模式匹配表达式。
让我们看看第一个check的定义:
第一个参数匹配true值。此函数将处理第一个数字大的情况。它将第一个数字绑定到变量number。第三个参数用于较小的数字,我们不需要它,所以用通配符表示。最后函数返回number变量。
再看看第二种情况:(www.xing528.com)
使用模式匹配检查第二个参数是否为false,此函数将处理第二个数字大的情况。第二个参数用于较小的数字,用通配符表示。然后我们将较大的数字绑定到变量other_number。在函数体内,我们返回other_number变量。通过创建它,我们涵盖了第二种可能——第二个数字较大的情况。
这样我们就用函数和模式匹配处理了这两种可能性。在Elixir中,我们将这些多重函数称为函数子句(function clause)。你可以根据需要创建任意多个函数子句,唯一的要求是必须连续地定义它们。这意味着无法在两个check函数的定义之间创建另一个函数。另外,调用多重函数时,函数子句的顺序非常重要,Elixir将执行第一个匹配的函数子句。
再看看我们的入口函数greater/2:
辅助函数check/3在第一个参数中传递>=运算的结果,在后两个参数中传递数字。然后,函数子句处理布尔值并返回较大的数字。其他开发者只要调用greater/2就能完成上述任务,而不需要理会check/3函数。check/3是用defp指令定义的私有函数。
defp指令用于定义模块的私有函数。私有函数无法从外部访问,它甚至无法从其他模块导入。如果我们在IEx会话中尝试调用check/3函数,则会引发UndefinedFunctionError,请看:
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。