Rust 是一门多范式的编程语言,但 Rust 的编程风格是更偏向于函数式的,函数在 Rust 中是“一等公民”。这意味着,函数是可以作为数据在程序中进行传递。
跟 C/C++/Go 一样,Rust 程序也有一个唯一的程序入口 main 函数,之前在 hello world 例子中已经见到过了:
fn main() {
}
Rust 使用 fn 关键字来声明和定义函数,后面跟着函数名,一对括号是因为这函数没有参数,然后是一对大括号代表函数体。下面是一个叫做 foo 的函数:
fn foo() {
}
如果函数有返回值,在括号后面加上箭头 -> ,接着是返回类型:
fn main() {
println!("{:?}", add(1, 2));
}
fn add(x: i32, y: i32) -> i32 {
x + y
}
add 函数可以将两个数值加起来并将结果返回。
语句和表达式
Rust 主要是一个基于表达式的语言。只有两种语句,其他的一切都是表达式。
这又有什么区别的?表达是返回一个值,而语句不是。这就是为甚恶魔这里我们以“不是所有控制路劲都返回一个值”结束:x + 1; 语句不返回一个值。Rust 中有两种类型的语句:“声明语句”和“表达式语句”。其余一切都是表达式。
声明语句
在一些语言中,变量绑定可以被写成一个表达式,不仅仅是语句。例如 Ruby:
x = y = 5
然而,在 Rust 中,使用 let 引入一个绑定并不是一个表达式。下面的代码会产生一个编译时错误:
let x = (let y = 5);
Blocking waiting for file lock on build directory
Compiling hello_world v0.1.0 (yourpath/hello_world)
error: expected expression, found statement (`let`)
--> main.rs:2:14
|
2 | let x = (let y = 5);
| ^^^
|
= note: variable declaration using `let` is a statement
error: aborting due to previous error
error: Could not compile `hello_world`.
编译器告诉我们这里它期望看到表达式的开头,而 let 只能开始一个语句,不是一个表达式。
注意赋值一个已经绑定过的变量(例如 y = 5)仍然时一个表达式,即使它的(返回)值并不是特别有用。不像其他语言中赋值语句返回它赋的值(例如,前面例子中的 5 ),在 Rust 中赋值的值是一个空元组 ():
let mut y = 5;
let x = (y = 6); // x has the value `()`, not `6`
表达式语句
表达式语句的目的是把任何表达式变为语句。在实践中,Rust 语法期望语句后面跟其他语句。这意味着用分号来分隔各个表达式。着意味着 Rust 看起来很像大部分其他使用分号作为语句结尾的语言,并且你会看到分号出现在几乎每一行 Rust 代码。
那么我们说“几乎”的例外是什么呢?比如:
fn add_one(x: i32) -> i32 {
x + 1;
}
我们的函数声称它返回一个 i32,不过带有一个分号的话,它将返回一个 ()。Rust 意识到这可能不是我们想要的,并在我们看到的错误中建议我们去掉分号:
Compiling hello_world v0.1.0 (yourpath/hello_world)
error[E0269]: not all control paths return a value
--> main.rs:1:1
|
1 | fn add_one(x: i32) -> i32 {
| ^
|
help: consider removing this semicolon:
--> main.rs:2:10
|
2 | x + 1;
| ^
error: aborting due to previous error
error: Could not compile `hello_world`.
fn add_one(x: i32) -> i32 {
x + 1
}
函数参数
参数声明
Rust 的函数参数声明和一般的变量声明非常相似:参数名加上冒号再加上参数类型,不过不需要 let 关键字。例如这个程序将两个数相加并打印结果:
fn main() {
print_sum(5, 6);
}
fn print_sum(x: i32, y: i32) {
println!("sum is: {}", x + y);
}
在调用函数和声明函数时,多个参数需要用逗号 , 分隔。与 let 不同的是,普通变量声明可以省略变量类型,而函数参数声明则不能省略参数类型。下面的代码不能够工作:
fn main() {
print_sum(5, 6);
}
fn print_sum(x, y) {
println!("sum is: {}", x + y);
}
编译器将会给出以下错误:
Compiling hello_world v0.1.0 (yourpath/h