TranslateProject/sources/tech/20230424.0 ⭐️⭐️ Rust Basics Series 5 Functions in the Rust Programming Language.md

257 lines
8.6 KiB
Markdown
Raw Normal View History

[#]: 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: " "
[#]: 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]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者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/