6、初识Rust – 函数

目录 编程

一、函数声明

函数在Rust中非常常见,例如非常重要的main 也是一个函数。

Rust 代码中的函数和变量名使用 snake case 规范风格。在 snake case 中,所有字母都是小写并使用下划线分隔单词。

fn main() {
     test_function();
}

fn test_function() {
     println!("test");
}

在Rust中使用 fn 后跟函数名和括号来定义,大括号来告诉编译起哪里是函数体的开始和结尾。

可以使用函数名后跟圆括号来调用我们定义过的任意函数。因为程序中已定义 test_function 函数,所以可以在 main 函数中调用它。注意,源码中 test_function 定义在 main 函数 之后;也可以定义在之前。Rust 不关心函数定义所在的位置,只要函数被调用时出现在调用之处可见的作用域内就行。

二、参数

我们可以定义拥有参数(parameters)的函数,参数是特殊变量,是函数签名的一部分。当函数拥有参数时,可以为这些参数提供具体的值。技术上讲,这些具体值被称为参数(arguments)。但是在日常交流中,人们倾向于不区分使用 parameter 和 argument 来表示函数定义中的变量或调用函数时传入的具体值。

fn main() {
   test_function(6);
}

fn test_function(x: i8) {
    println!("{x}");
}

当传递多个参数时,使用逗号分隔参数。

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

fn test_function(x: i8, y: i8) {
    println!("{x},{y}");
}

三、语句和表达式

函数一般由一系列语句和一个可选的结尾表达式构成。Rust是一门基于表达式的语言(expression-based),这是一个相对其它编程语言的一个区别。

以下let a = 6为一个语句。

fn main() {
    let a = 6;
}

语句不能像一般编程语言那样把let语句附值给另一个变量,比如下面这样就会抛出错误。

fn main() {
    let a = (let y = 6);
}

let 不会返回值,所以无法绑定y上的值,这点和其它语言都不一样。如果想要这样写则需要以表达式的形式,表达式可以是语句的一部分。如let a = 6;这个6就是一个表达式,它计算出的值是6,同时也可以使用大括号创建表达式。

fn main() {
    let a = {
        let y = 2;
        y + 1
    }
}

例如上面这个大括号作用域,也属于一个表达式,最后y + 1的结果就会附值给a变量。但是需要注意 y + 1后面不可以加分号,加了分号这句代码就会变成一个语句,语句将不会返回值。

四、函数返回值

函数可以向调用它的代码返回值。在Rust中不需要对返回值命名,但是需要为其指定类型。

fn main() {
    let c = test_function(1,2);
    println!("{c}");
}

fn test_function(a: i8, b: i8) -> i8 {
    a + b
}

如上面,在test_function函数后加上 -> 并指定返回值即可。

但是特别需要注意下面这段代码;

fn main() { 
    let c = test_function(1,2);
    println!("{c}");
} 

fn test_function(a: i8, b: i8) -> i8 { 
    a + b;
}

这段代码运行后就会产生如下一个错误。

–> src/main.rs:6:35
|
6 | fn test_function(a: i8, b: i8) -> i8 {
| ————- ^^ expected `i8`, found `()`
| |
| implicitly returns `()` as its body has no tail or `return` expression
7 | a + b;
| – help: remove this semicolon

For more information about this error, try `rustc –explain E0308`.
error: could not compile `master` due to previous error

解决办法提示有2个,一个是去掉返回值,另一个是去掉 a + b 后面的分号。

为什么会这样呢?这个问题又得回到语句和表达式上,因为语句没有返回值函数也属于一个作用域,作用域可以使用表达式的方式返回值,而当a + b后面加上分号后,这个表达式就会变成语句,语句不会返回值,当不返回值时会与函数定义产生冲突,从而报错。