Home

Rust 2.6 函数

10 Jan 2015 by LelouchHe

原文链接

你已经见过一个函数了,main函数:

fn main() {
}

这是最简单的函数声明了.以前提到过,fn表示这是一个函数,紧接着是函数名,小括号表示没有参数,然后是大括号的函数体.下面是函数foo:

fn foo() {
}

如何加入参数呢?下面就是一个打印数字的函数:

fn print_number(x: i32) {
    println!("x is: {}", x);
}

下面是一段完整程序:

fn main() {
    print_number(5);
}

fn print_number(x: i32) {
    println!("x is {}", x);
}

可以看到,函数参数类似于let声明:在参数名称后面加上冒号和类型名称.

下面是一段2整数相加并打印的程序:

fn main() {
    print_sum(5, 6);
}

fn print_sum(x: i32, y: i32) {
    println!("sum is: {}", x + y);
}

当你声明和调用函数时,要使用逗号来分隔不同的参数.

let不同,函数参数是必须声明类型的.下面这个无法编译通过:

fn print_sum(x, y) {
    println!("sum is: {}", x + y);
}

会有下面的错误:

error: expected one of `!`, `:`, or `@`, found `,`

这是特意的设计.尽管全程序内的类型推导是可能的,但有类似机制的语言,比如Haskell,通常都建议明确的写出类型来.我们认为,在全类型推导和无类型推导中间,强制函数声明参数类型,但在函数体内进行类型推导是合适的.

如何返回值呢?下面就是给数字加1的函数:

fn add_one(x: i32) -> i32 {
    x + 1
}

Rust函数只返回一个值,这个值的类型写在箭头(“->”)之后.

你看,函数体内没有分号.如果我们加上:

fn add_one(x: i32) -> i32 {
    x + 1;
}

我们会得到如下错误:

error: not all control paths return a value
help: consider removing thie semicolon:
    x + 1;
         ^

还记得讨论的分号的()么?我们的函数声明返回i32,但由于这个分号,结果会返回().Rust知道这可能不是我们想要的,所以建议去掉分号.

这很像我们曾经提到过的if: 大括号(“{ … }”)的值,是表达式的值.对于Ruby一样的基于表达式的语言是很常见的,但对于系统编程语言是少见的.第一次碰见这个情况,人们通常假定这会带来bug(译者: 应该是说结尾增减分号的建议).但Rust的类型系统非常强大,而且unit类型非常特殊,所以我们从来没有见过增减分号会带来问题的.

想要提前返回怎么办?Rust有一个return关键字:

fn foo(x: i32) -> i32 {
    if x < 5 {
        return x;
    }

    x + 1
}

函数的最后一行使用return也是可以的,但通常不建议这样做:

fn foo(x: i32) -> i32 {
    if x < 5 {
        return x;
    }

    return x + 1;
}

还有其他的方式可以来定义函数,但这涉及到一些我们还没提到的概念,所以就先到这里.