12.9 小结
Julia 中的函数是很有特色的。它用一种很惊艳的方式——多重分派——达成了对多态性调用的支持。不仅如此,函数还可以被参数化,以满足我们对多态性参数及结果的要求。这使得一个函数定义能够自动地同时向着多个维度进行扩展,从而可以大大减少我们的代码量,也在很大程度上提高了我们编码的效率。
在本章,我们先回顾了数学中的函数,然后延伸到了程序中的函数。Julia 语言中的函数与数学中的函数很相近。我们可以用一种简洁形式在 Julia 程序中定义函数。这样的话,它们看起来就更像数学函数了。当然了,我们在一般情况下会使用标准的形式来定义函数。标准的函数定义会包含关键字function
和end
,而且其函数体还可以占据多行。另外,我们不但可以为一个函数的任何参数声明类型,还可以把它的参数声明为位置参数或关键字参数,以及必选参数或可选参数。相比之下,函数的结果声明就简单多了。因为它只能有一个类型声明。虽然 Julia 函数的结果原则上只能有一个,但我们却可以让它同时返回多个结果值。这时,Julia 会自动地把多个结果值包装成一个元组。
除此之外,我们还讲述了非常重要的一点,那就是:Julia 中的函数又可以被分为泛化函数和衍生方法。我们通常定义的函数其实都是基于某个泛化函数的衍生方法。同一个泛化函数下的衍生方法的名称一定是相同的。然而,这些衍生方法的位置参数列表肯定是不同的,或是参数的数量不一,或是参数的类型各异,或是兼而有之。另外,它们所属的模块也可以是不同的。
当我们对一个泛化函数进行调用时,Julia 会利用它的多重分派机制选择最匹配的那个衍生方法去承接调用。如果存在那样的衍生方法,那么函数调用就将是非常顺滑的。否则,Julia 就会立即报错,并告知我们找不到匹配的衍生方法。另外还要注意,包含了可选的位置参数的函数定义会被 Julia 同时解析为多个衍生方法。这可能会导致一些不符合我们预期的方法覆盖。
一旦搞懂了本章所讲的这些知识,我们就可以去编写逻辑任意复杂的程序了。要知道,在 Julia 中,函数无疑是最主要的程序载体。绝大部分的表达式、语句和代码块都可以被放置在函数体里面。另外,函数也是非常重要的代码块和作用域。
通常,正规的程序都会有一系列函数负责把整个流程串起来。因为这样做可以让流程中的每一个步骤都清晰、易懂。毫不夸张地讲,会用函数、善用函数是我们成为合格的程序开发者的必要条件。我希望你能通过对本章内容的理解,向着优秀开发者的阵营大步挺进。