【在主画面加入捷径】
       
【选择语系】
繁中 简中

Rust 程序设计教学:函式 (Function)

【赞助商连结】

    在前面的内容中,我们将大部分的程序代码写在主函式中。随着程序规模上升,这种方式渐渐显得不足:(1) 对于相同的步骤撰写重覆的程序代码,(2) 主程序变得冗长,(3) 无法将程序代码分离再利用。函式 (function) 是程序代码再利用的基础,透过函式将程序代码分离后,可再将函式整理成函式库 (library) 分享给其他程序。面向对象程序设计 (object-oriented programming) 的方法 (method),也是建立在函式之上。

    使用函式

    Rust 预先写好许多的函式,供程序设计者使用,在先前的例子中,我们已经使用过一些函式和物件。以下是一个例子:

    在本例中,我们调用标准函式库的 f64 模块,接着,调用 sqrt函数。有时候,函式会和物件结合,在本书先前介绍容器时,就介绍了一些 Rust 内建的容器物件;和物件相连的函式,也称为方法 (method)。

    撰写函式

    撰写函式或方法使用 fn 这个关键字。我们来看一个简单的实例:

    在本例中,hello函数相当单纯,每次调用时都会在终端机中印出 Hello, World 字串。由此可以看出,将程序代码写入函式后,可以重覆调用。

    在上例中,hello函数的行为是固定的。函式可透过参数 (parameter) 来改变函式的行为。如下例:

    在本例中,我们输入不同的名字,hello函数会印出不同的字串。虽然 Rust 可自动推断类型,在撰写 Rust函数时,必需明确指定参数的类型,这是 Rust 设计上的考量。

    除了可以传入参数,函式也可以有回传值 (returning value),如下例:

    在本例中,我们依据所到的字符来回传不同的值,若字符为空,回传一个空字串,若字符不为空,则将首字母转为大写后和其他字符相接后回传。要注意的是,回传值后不加上分号 (;),在 Rust 中,没加分号的是表达式 (expression),而有加分号的是叙述 (statement)。以下是一个错误的例子:

    若改成表达式,则正确:

    若不习惯这种语法,也可改为回传叙述:

    回传表达式,是比较典型的 Rust 习惯语法。

    Rust 的函式只能回传单一值,而 Rust 发展出一些特殊容器来应对。例如前文提过的 Option 容器,可回传 None 表空值或是以 Some 包装的参考。另外一个例子是 Result 容器,可回传值或是表示错误的 Err。

    改变状态的函式

    若搭配参考 (reference),函式也可改变数据的状态。如下例:

    有 C 语言经验的读者,应该可以发现本例采用 C 风格的面向对象。由于 Rust 本身即支援面向对象,在实务上不建议这种写法,这个范例仅是展示如何在函式中使用参考。

    ##函数指针

    函式可以视为一种类型,也可将函式视为值。如下例:

    在这里,也可以用 Rust 的类型推断功能,将类型省略。在程序中能够将函式视为值是函数式程序设计的基础,详见后续文章。

    默认参数

    Rust 的函式不支援默认参数,要用其他的方式来仿真这个特性。其中一个方式是利用 Default trait,范例如下:

    在这个例子中,我们运用一点点面向对象的功能,将 Parameter 结构加人 default函数,之后就可以调用此函式以得到默认值。Rust 大量运用 trait 实现面向对象及泛型相关的功能,想了解的读者可在后续的章节看到更多范例。

    递归

    递归 (recursion) 是可以调用自己的函式,直到回到某个特定的基本条件为止。Fibonacci 数是一个典型的递归实例,程序代码范例如下:

    初学者对递归程序感到困惑,而不知道如何追踪递归程序代码。递归函式就像是一般的函式般,是完成某个特定的行为的蓝图,而不是该行为本身。递归函式会在某个递归的步骤告诉电脑「在这里我们要再调用一次这个方法,帮我完成这个步骤,然后将结果传回来」。另外一个学习递归的方法,是重新将数学归纳法 (mathematical induction) 的教材看一次,这两者间有异曲同工之妙。要写好递归程序,关键在于设置正确的终止条件。以 Fibonacci 数来说,有两个终止条件,即 F(0) = 1 和 F(1) = 1,其他的数字,最后都会调用到这两个数字。

    在程序设计中,递归是相当重要的概念,许多用控制流程的程序都可用递归重新改写。使用递归实现程序,代码往往更为简洁。许多数据结构和算法的内部,也大量使用递归,像是堆 (heap)、树 (tree)、图 (graph)等。

    【赞助商连结】
    TAGS: FUNCTION, RUST