mirror of
https://github.com/LCTT/TranslateProject.git
synced 2024-12-26 21:30:55 +08:00
[提交翻译][tech]: 20230424.0 ⭐️⭐️ Rust Basics Series 5 Functions in the Rust Programming Language (#29436)
* [翻译完成][tech]: 20230424.0 ⭐️⭐️ Rust Basics Series 5 Functions in the Rust Programming Language * [移动翻译][tech]: 20230424.0 ⭐️⭐️ Rust Basics Series 5 Functions in the Rust Programming Language
This commit is contained in:
parent
3ccb0c551c
commit
4ac0acd0a4
@ -1,256 +0,0 @@
|
||||
[#]: 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 Basics Series #5: Functions in the Rust Programming Language
|
||||
======
|
||||
|
||||
Like any modern programming language, Rust too has functions.
|
||||
|
||||
The function that you are already familiar with is the `main` function. This function gets called when the program is launched.
|
||||
|
||||
But what about other functions? In this article, you'll learn to use functions in Rust programs.
|
||||
|
||||
### The basic syntax of a function
|
||||
|
||||
You may already know this based on how we declare the `main` function, but let's look at the syntax of declaring a function nonetheless.
|
||||
|
||||
```
|
||||
// declaring the function
|
||||
fn function_name() {
|
||||
<statement(s)>;
|
||||
}
|
||||
|
||||
// calling the function
|
||||
function_name();
|
||||
```
|
||||
|
||||
Let's look at a simple function that prints the string "Hi there!" to the standard output.
|
||||
|
||||
```
|
||||
fn main() {
|
||||
greet();
|
||||
}
|
||||
|
||||
fn greet() {
|
||||
println!("Hi there!");
|
||||
}
|
||||
```
|
||||
|
||||
> 📋 Unlike C, it does not matter if you call the function before declaring or defining it. As long as the said function is declared
|
||||
|
||||
_somewhere_
|
||||
|
||||
, Rust will handle it.
|
||||
|
||||
And as expected, it has the following output:
|
||||
|
||||
```
|
||||
Hi there!
|
||||
```
|
||||
|
||||
That was simple. Let's take it to the next level. Let's create functions that accept parameter(s) and return value(s). Neither are mutually exclusive or inclusive.
|
||||
|
||||
### Accepting parameters with functions
|
||||
|
||||
The syntax for a function that accepts the parameter is as follows:
|
||||
|
||||
```
|
||||
// declaring the function
|
||||
fn function_name(variable_name: type) {
|
||||
<statement(s)>;
|
||||
}
|
||||
|
||||
// calling the function
|
||||
function_name(value);
|
||||
```
|
||||
|
||||
You can think of the function parameters as a [tuple][1] that is passed to the function. It can accept parameters of multiple data types and as many as you wish. So, you are not restricted to accepting parameters of the same type.
|
||||
|
||||
Unlike some languages, Rust does not have _default arguments_. **Populating all parameters when calling the function is compulsory**.
|
||||
|
||||
#### Example: Famished function
|
||||
|
||||
Let's look at a program to understand this better.
|
||||
|
||||
```
|
||||
fn main() {
|
||||
food(2, 4);
|
||||
}
|
||||
|
||||
fn food(theplas: i32, rotis: i32) {
|
||||
println!(
|
||||
"I am hungry... I need {} theplas and {} rotis!",
|
||||
theplas, rotis
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
On line 5, I declare a function called `food`. This function takes in 2 parameters: `theplas` and `rotis` (Names of Indian food items). I then print the contents of these variables.
|
||||
|
||||
From the `main` function, I call the `food` function with parameters '2' and '4'. This means that `theplas` gets assigned the value '2' and `rotis` get assigned the value '4'.
|
||||
|
||||
Let's look at the program output:
|
||||
|
||||
```
|
||||
I am hungry... I need 2 theplas and 4 rotis!
|
||||
```
|
||||
|
||||
And now I'm actually hungry... 😋
|
||||
|
||||
### Returning values from a function
|
||||
|
||||
Just as a function can accept values in the form of parameters, a function can also return one or more values. The syntax for such a function is as follows:
|
||||
|
||||
```
|
||||
// declaring the function
|
||||
fn function_name() -> data_type {
|
||||
<statement(s)>;
|
||||
}
|
||||
|
||||
// calling the function
|
||||
let x = function_name();
|
||||
```
|
||||
|
||||
The function can return a value using either the `return` keyword or by using an expression instead of a statement.
|
||||
|
||||
Wait! Expression what?
|
||||
|
||||
#### Before you go further: Statements vs Expressions
|
||||
|
||||
It may not fit in the flow of the Rust function examples but you should understand the difference between statements and expressions in Rust and other programming languages.
|
||||
|
||||
A statement is a line of code that ends with a semi-colon and _does not evaluate to some value_. An expression, on the other hand, is a line of code that does not end with a semi-colon and evaluates to some value.
|
||||
|
||||
Let's understand that with an example:
|
||||
|
||||
```
|
||||
fn main() {
|
||||
let a = 873;
|
||||
let b = {
|
||||
// statement
|
||||
println!("Assigning some value to a...");
|
||||
|
||||
// expression
|
||||
b * 10
|
||||
};
|
||||
|
||||
println!("a: {a}");
|
||||
}
|
||||
```
|
||||
|
||||
On line 3, I open a code block, inside which I have a statement and an expression. The comments highlight which one is which.
|
||||
|
||||
The code on the 5th line does not evaluate to a value and hence needs to be ended with a semi-colon. This is a statement.
|
||||
|
||||
The code on the 8th line evaluates to a value. It is `b * 10` which is `873 * 10` and it evaluates to `8730`. Since this line does not end with a semi-colon, this is an expression.
|
||||
|
||||
> 📋 An expression is a handy way of returning something from a code block. Hence, it is an alternate to the `return` keyword when a value is returned. The expressions are not only used to "return" a value from a function. As you just saw, the value of `b * 10` was "returned" from the inner scope to the outer scope and it was assigned to the variable `b`. A simple scope isn't a function and the value of the expression was still "returned".
|
||||
|
||||
#### Example: Buying rusted fruits
|
||||
|
||||
Let's understand how a function returns a value using a demonstration.
|
||||
|
||||
```
|
||||
fn main() {
|
||||
println!(
|
||||
"If I buy 2 Kilograms of apples from a fruit vendor, I have to pay {} rupees to them.",
|
||||
retail_price(2.0)
|
||||
);
|
||||
println!(
|
||||
"But, if I buy 30 Kilograms of apples from a fruit vendor, I have to pay {} rupees to them.",
|
||||
wholesale_price(30.0)
|
||||
);
|
||||
}
|
||||
|
||||
fn retail_price(weight: f64) -> f64 {
|
||||
return weight * 500.0;
|
||||
}
|
||||
|
||||
fn wholesale_price(weight: f64) -> f64 {
|
||||
weight * 400.0
|
||||
}
|
||||
```
|
||||
|
||||
Above I have two functions: `retail_price` and `wholesale_price`. Both functions accept one parameter and store the value inside the `weight` variable. This variable is of type `f64` and the function signature denotes that an `f64` value is ultimately returned by the function.
|
||||
|
||||
Both of these functions multiply the weight of apples purchased by a number. This number represents the current price per Kilogram for apples. Since wholesale purchasers have big orders, logistics are easier in a way, the price can be eased a bit.
|
||||
|
||||
Other than the price per Kilogram, the functions have one more difference. That is, the `retail_price` function returns the product using the `return` keyword. Whereas, the `wholesale_price` function returns the product using an expression.
|
||||
|
||||
```
|
||||
If I buy 2 Kilograms of apples from a fruit vendor, I have to pay 1000 rupees to them.
|
||||
But, if I buy 30 Kilograms of apples from a fruit vendor, I have to pay 12000 rupees to them.
|
||||
```
|
||||
|
||||
The output shows that both methods of returning a value from a function work as intended.
|
||||
|
||||
#### Returning multiple values
|
||||
|
||||
You can have a function that returns multiple values of different types. You have many options, but returning a tuple is the easiest.
|
||||
|
||||
Following is an example:
|
||||
|
||||
```
|
||||
fn main() {
|
||||
let (maths, english, science, sanskrit) = tuple_func();
|
||||
|
||||
println!("Marks obtained in Maths: {maths}");
|
||||
println!("Marks obtained in English: {english}");
|
||||
println!("Marks obtained in Science: {science}");
|
||||
println!("Marks obtained in Sanskrit: {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)
|
||||
}
|
||||
```
|
||||
|
||||
The `tuple_func` returns four `f64` values, enclosed in a tuple. These values are the marks obtained by a student in four subjects (out of 100).
|
||||
|
||||
When the function is called, this tuple is returned. I can either print the values using `tuple_name.0` scheme, but I thought it best to destruct the tuple first. That will ease the confusion of which value is which. And I print the marks using the variables that contain values from the destructured tuple.
|
||||
|
||||
Following is the output I get:
|
||||
|
||||
```
|
||||
Marks obtained in Maths: 84.5
|
||||
Marks obtained in English: 85
|
||||
Marks obtained in Science: 75
|
||||
Marks obtained in Sanskrit: 67.25
|
||||
```
|
||||
|
||||
### Conclusion
|
||||
|
||||
This article covers functions in the Rust programming language. The "types" of functions are covered here:
|
||||
|
||||
- Functions that do not accept any parameter(s) nor return value(s)
|
||||
- Functions that accept one or more parameters
|
||||
- Functions that return one or more values back to the caller
|
||||
|
||||
You know what comes next? Conditional statements aka if-else in Rest. Stay tuned and enjoy learning Rust with It's FOSS.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
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://itsfoss.com/rust-arrays-tuples/
|
@ -0,0 +1,252 @@
|
||||
[#]: 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
|
Loading…
Reference in New Issue
Block a user