Rust 基础系列 #5: Rust 中的函数
在这一章中，在实例的帮助下，学习如何使用函数并从中返回值。
Rust
在这一章中，在实例的帮助下，学习如何使用函数并从中返回值。
![](/data/attachment/album/202305/29/150550h23qbhahwzb66hb1.jpg)



> 
> 在这一章中，在实例的帮助下，学习如何使用函数并从中返回值。
> 
> 
> 


就跟任何现代编程语言一样，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);

```

你可以把函数参数想象成一个传递给函数的 [元组](/article-15837-1.html)。它可以接受多种数据类型的参数，而且你可以接受任意多个参数。所以，你不必局限于接受相同类型的参数。


与某些语言不同的是，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。请继续关注并享受学习 Rust 的过程。


*（题图：MJ/5a07503b-c691-4276-83b2-bb42f5fda347）*




---


via: <https://itsfoss.com/rust-functions/>


作者：[Pratham Patel](https://itsfoss.com/author/pratham/) 选题：[lkxed](https://github.com/lkxed/) 译者：[Cubik65536](https://github.com/Cubik65536) 校对：[wxy](https://github.com/wxy)


本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出

