mirror of
https://github.com/LCTT/TranslateProject.git
synced 2024-12-23 21:20:42 +08:00
253 lines
8.0 KiB
Markdown
253 lines
8.0 KiB
Markdown
|
[#]: subject: "Rust Basics Series #5: Functions in the Rust Programming Language"
|
|||
|
[#]: via: "https://itsfoss.com/rust-functions/"
|
|||
|
[#]: author: "Pratham Patel https://itsfoss.com/author/pratham/"
|
|||
|
[#]: collector: "lkxed"
|
|||
|
[#]: translator: "Cubik65536"
|
|||
|
[#]: reviewer: " "
|
|||
|
[#]: publisher: " "
|
|||
|
[#]: url: " "
|
|||
|
|
|||
|
Rust 基础系列 #5: Rust 中的函数
|
|||
|
======
|
|||
|
|
|||
|
就跟任何现代编程语言一样,Rust 也有函数。
|
|||
|
|
|||
|
你已经熟悉的函数是 `main` 函数。这个函数在程序启动时被调用。
|
|||
|
|
|||
|
但是其他函数呢?在本文中,你将学习如何在 Rust 程序中使用函数。
|
|||
|
|
|||
|
### 函数的基本语法
|
|||
|
|
|||
|
你可能已经在我们声明 `main` 函数时知道了这一点,不管怎么样,还是让我们看一下声明函数的语法。
|
|||
|
|
|||
|
```
|
|||
|
// 声明函数
|
|||
|
fn function_name() {
|
|||
|
<statement(s)>;
|
|||
|
}
|
|||
|
|
|||
|
// 调用函数
|
|||
|
function_name();
|
|||
|
```
|
|||
|
|
|||
|
来让我们看一个简单的函数,它将字符串 "Hi there!" 打印到标准输出。
|
|||
|
|
|||
|
```
|
|||
|
fn main() {
|
|||
|
greet();
|
|||
|
}
|
|||
|
|
|||
|
fn greet() {
|
|||
|
println!("Hi there!");
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
> 📋 与 C 不一样的是,不管你是否要在声明或定义之前调用函数都没有关系。只要这个函数在 _某个地方_ 被声明了,Rust 就会处理它。
|
|||
|
|
|||
|
正如预期,它的输出如下:
|
|||
|
|
|||
|
```
|
|||
|
Hi there!
|
|||
|
```
|
|||
|
|
|||
|
这挺简单的。让我们把它提升到下一个级别。让我们创建一个接受参数并返回值的函数。两者都不是互斥的,也不是包容的。
|
|||
|
|
|||
|
### 使用函数接受参数
|
|||
|
|
|||
|
声明一个接受参数的函数的语法如下:
|
|||
|
|
|||
|
```
|
|||
|
// 声明函数
|
|||
|
fn function_name(variable_name: type) {
|
|||
|
<statement(s)>;
|
|||
|
}
|
|||
|
|
|||
|
// 调用函数
|
|||
|
function_name(value);
|
|||
|
```
|
|||
|
|
|||
|
你可以把函数参数想象成一个传递给函数的 [元组][1]。它可以接受多种数据类型的参数,而且你可以接受任意多个参数。所以,你不必局限于接受相同类型的参数。
|
|||
|
|
|||
|
与某些语言不同的是,Rust 没有 _默认参数_。**在调用函数时填充所有参数是强制性的**。
|
|||
|
|
|||
|
#### 示例:饥饿函数
|
|||
|
|
|||
|
来让我们看一个程序来更好地理解这个。
|
|||
|
|
|||
|
```
|
|||
|
fn main() {
|
|||
|
food(2, 4);
|
|||
|
}
|
|||
|
|
|||
|
fn food(theplas: i32, rotis: i32) {
|
|||
|
println!(
|
|||
|
"我饿了... 我需要 {} 个葫芦巴叶饼和 {} 个罗提!",
|
|||
|
theplas, rotis
|
|||
|
);
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
在第 5 行,我声明了一个名为 `food` 的函数。这个函数接受 2 个参数:`theplas` 和 `rotis`(印度食物的名字)。然后我打印了这些变量的内容。
|
|||
|
|
|||
|
对于 `main` 函数,我使用参数 '2' 和 '4' 调用 `food` 函数。这意味着 `theplas` 被赋值为 '2',`rotis` 被赋值为 '4'。
|
|||
|
|
|||
|
来让我们看一下程序的输出:
|
|||
|
|
|||
|
```
|
|||
|
我饿了... 我需要 2 个葫芦巴叶饼和 4 个罗提!
|
|||
|
```
|
|||
|
|
|||
|
我现在真的饿了... 😋
|
|||
|
|
|||
|
### 从函数返回值
|
|||
|
|
|||
|
就像函数可以接受参数一样,函数也可以返回一个或多个值。这样的函数的语法如下:
|
|||
|
|
|||
|
```
|
|||
|
// 声明函数
|
|||
|
fn function_name() -> data_type {
|
|||
|
<statement(s)>;
|
|||
|
}
|
|||
|
|
|||
|
// 调用函数
|
|||
|
let x = function_name();
|
|||
|
```
|
|||
|
|
|||
|
函数可以使用 `return` 关键字或者使用表达式而不是语句来返回一个值。
|
|||
|
|
|||
|
等等!什么是表达式?
|
|||
|
|
|||
|
#### 在进一步之前:语句与表达式
|
|||
|
|
|||
|
在讲解 Rust 函数的例子中提起这个可能不太合适,但是你应该理解 Rust 和其他编程语言中语句和表达式的区别。
|
|||
|
|
|||
|
语句是以分号结尾且 _不会计算出某个值_ 的代码行。另一方面,表达式是一行不以分号结尾且计算出某个值的代码行。
|
|||
|
|
|||
|
来让我们用一个例子来理解:
|
|||
|
|
|||
|
```
|
|||
|
fn main() {
|
|||
|
let a = 873;
|
|||
|
let b = {
|
|||
|
// 语句
|
|||
|
println!("Assigning some value to b...");
|
|||
|
|
|||
|
// 表达式
|
|||
|
a * 10
|
|||
|
};
|
|||
|
|
|||
|
println!("b: {b}");
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
在第 3 行,我开始了一个代码块,在这个代码块中我有一个语句和一个表达式。注释标明了哪个是哪个。
|
|||
|
|
|||
|
在第 5 行的代码不会计算出某个值,因此需要以分号结尾。这是一个语句。
|
|||
|
|
|||
|
第 8 行的代码计算出了一个值。它是 `a * 10`(`873 * 10`),并计算出了 `8730`。因为这一行没有以分号结尾,所以这是一个表达式。
|
|||
|
|
|||
|
> 📋 使用表达式是从代码块中返回某些东西的一种方便的方法。因此,当返回一个值时,它是 `return` 关键字的替代方案。表达式不仅仅用于从函数中“返回”一个值。正如你刚刚看到的,`a * 10` 的值是从内部作用域“返回”到外部作用域,并赋值给变量 `b`。一个简单的作用域不是一个函数,但表达式的值仍然被“返回”了。
|
|||
|
|
|||
|
#### 示例:购买腐烂的水果
|
|||
|
|
|||
|
来让我们看一个演示以理解函数如何返回一个值:
|
|||
|
|
|||
|
```
|
|||
|
fn main() {
|
|||
|
println!(
|
|||
|
"如果我从水果摊买了 2 公斤苹果,我必须付给他们 {} 印度卢比。",
|
|||
|
retail_price(2.0)
|
|||
|
);
|
|||
|
println!(
|
|||
|
"但是,如果我从水果摊买了 30 公斤苹果,我就要付给他们 {} 印度卢比。",
|
|||
|
wholesale_price(30.0)
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
fn retail_price(weight: f64) -> f64 {
|
|||
|
return weight * 500.0;
|
|||
|
}
|
|||
|
|
|||
|
fn wholesale_price(weight: f64) -> f64 {
|
|||
|
weight * 400.0
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
我在上述代码中有两个函数:`retail_price` 和 `wholesale_price`。两个函数都接受一个参数并将值存储在 `weight` 变量中。这个变量的类型是 `f64`,函数签名表示最终函数返回一个 `f64` 值。
|
|||
|
|
|||
|
这两个函数都将购买的苹果的重量乘以一个数字。这个数字表示苹果的当前每公斤价格。由于批发商有大量订单,物流在某种程度上更容易,价格可以降低一点。
|
|||
|
|
|||
|
除了每公斤价格之外,这两个函数还有一个区别。那就是,`retail_price` 函数使用 `return` 关键字返回乘积。而 `wholesale_price` 函数使用表达式返回乘积。
|
|||
|
|
|||
|
```
|
|||
|
如果我从水果摊买了 2 公斤苹果,我必须付给他们 1000 印度卢比。
|
|||
|
但是,如果我从水果摊买了 30 公斤苹果,我就要付给他们 12000 印度卢比。
|
|||
|
```
|
|||
|
|
|||
|
输出显示,从函数返回值的两种方法都按预期工作。
|
|||
|
|
|||
|
#### 返回多个值
|
|||
|
|
|||
|
你可以有一个返回不同类型的多个值的函数。你有很多选择,但返回一个元组是最简单的。
|
|||
|
|
|||
|
接下来是一个示例:
|
|||
|
|
|||
|
```
|
|||
|
fn main() {
|
|||
|
let (maths, english, science, sanskrit) = tuple_func();
|
|||
|
|
|||
|
println!("数学考试得分: {maths}");
|
|||
|
println!("英语考试得分: {english}");
|
|||
|
println!("科学考试得分: {science}");
|
|||
|
println!("梵语考试得分: {sanskrit}");
|
|||
|
}
|
|||
|
|
|||
|
fn tuple_func() -> (f64, f64, f64, f64) {
|
|||
|
// return marks for a student
|
|||
|
let maths = 84.50;
|
|||
|
let english = 85.00;
|
|||
|
let science = 75.00;
|
|||
|
let sanskrit = 67.25;
|
|||
|
|
|||
|
(maths, english, science, sanskrit)
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
函数 `tuple_func` 返回 4 个封装在一个元组中的 `f64` 值。这些值是一个学生在四门科目(满分 100 分)中获得的分数。
|
|||
|
|
|||
|
当函数被调用时,这个元组被返回。我可以使用 `tuple_name.0` 方案打印这些值,但我认为最好先解构元组,这样可以帮助我们搞清楚值对应的是什么。然后我使用了包含被解构的元组的值的变量来打印分数。
|
|||
|
|
|||
|
这是我得到的输出:
|
|||
|
|
|||
|
```
|
|||
|
数学考试得分: 84.5
|
|||
|
英语考试得分: 85
|
|||
|
科学考试得分: 75
|
|||
|
梵语考试得分: 67.25
|
|||
|
```
|
|||
|
|
|||
|
### 总结
|
|||
|
|
|||
|
本文介绍了 Rust 编程语言中的函数。这些是函数的“类型”:
|
|||
|
|
|||
|
- 不接受任何参数也不返回任何值的函数
|
|||
|
- 接收一个或多个参数的函数
|
|||
|
- 给调用者返回一个或多个值的函数
|
|||
|
|
|||
|
你知道接下来是什么吗?Rust 中的条件语句,也就是 if-else。请继续关注并享受在 Linux 中国学习 Rust 的过程。
|
|||
|
|
|||
|
--------------------------------------------------------------------------------
|
|||
|
|
|||
|
via: https://itsfoss.com/rust-functions/
|
|||
|
|
|||
|
作者:[Pratham Patel][a]
|
|||
|
选题:[lkxed][b]
|
|||
|
译者:[Cubik65536](https://github.com/Cubik65536)
|
|||
|
校对:[校对者ID](https://github.com/校对者ID)
|
|||
|
|
|||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
|||
|
|
|||
|
[a]: https://itsfoss.com/author/pratham/
|
|||
|
[b]: https://github.com/lkxed/
|
|||
|
[1]: https://linux.cn/article-15837-1.html
|