Перейти к содержимому

Функции в Rust

Функция — это именованный блок кода, который можно использовать много раз. Вместо того чтобы снова и снова писать одни и те же шаги, ты один раз кладёшь их в функцию и вызываешь её, когда нужно. Одной функцией ты уже пользуешься: это main.

Функция объявляется словом fn, а вызывается по имени, за которым идут ():

fn greet() {
println!("Привет из функции!");
}
fn main() {
greet(); // вызываем её
greet(); // и ещё раз
}

Вывод:

Привет из функции!
Привет из функции!
▶ Попробуй сам

Функции становятся полезными, когда ты передаёшь им данные для работы. Эти входные данные называются параметрами. В Rust тип каждого параметра обязательно нужно указать:

fn greet(name: &str) {
println!("Привет, {name}!");
}
fn main() {
greet("Алиса");
greet("Боб");
}

Вывод:

Привет, Алиса!
Привет, Боб!
▶ Попробуй сам

Параметров может быть сколько угодно, через запятую:

fn describe(name: &str, age: u32) {
println!("{name}: {age} лет");
}
fn main() {
describe("Феррис", 10);
}

Вывод:

Феррис: 10 лет
▶ Попробуй сам

Переданные значения сопоставляются с параметрами по порядку: первое значение попадает в name, второе — в age. Если перепутать порядок, например describe(10, "Феррис"), будет ошибка компиляции, потому что типы не совпадут.

Функция может вернуть значение тому, кто её вызвал. Тип результата указывается после стрелки ->:

fn add(a: i32, b: i32) -> i32 {
a + b
}
fn main() {
let sum = add(3, 4);
println!("3 + 4 = {sum}");
}

Вывод:

3 + 4 = 7
▶ Попробуй сам

Заметь, что после a + b в примере выше нет точки с запятой. Это ключевая идея Rust:

  • Выражение без точки с запятой — это значение, которое возвращается.
  • Точка с запятой превращает его в инструкцию, которая ничего не возвращает.

Поэтому такой код ломается:

fn add(a: i32, b: i32) -> i32 {
a + b; // ❌ точка с запятой значит «ничего не возвращать», а мы обещали i32
}

Компилятор пожалуется, что функция должна вернуть i32, но не возвращает. Просто убери точку с запятой в последней строке.

fn square(n: i32) -> i32 {
n * n
}
fn main() {
let result = square(5);
println!("5 в квадрате — это {result}");
}

Вывод:

5 в квадрате — это 25
▶ Попробуй сам

Напиши функцию to_fahrenheit, которая принимает температуру в градусах Цельсия как f64 и возвращает её в градусах Фаренгейта. Формула: c * 9.0 / 5.0 + 32.0. Вызови её для 0, 100 и 37 градусов. Подсказка: сигнатура — fn to_fahrenheit(c: f64) -> f64, а тело — одно выражение без точки с запятой.

Показать решение
fn to_fahrenheit(c: f64) -> f64 {
c * 9.0 / 5.0 + 32.0
}
fn main() {
println!("0°C — это {}°F", to_fahrenheit(0.0));
println!("100°C — это {}°F", to_fahrenheit(100.0));
println!("37°C — это {}°F", to_fahrenheit(37.0));
}

Вывод:

0°C — это 32°F
100°C — это 212°F
37°C — это 98.6°F
▶ Попробуй сам

Обрати внимание: мы передаём 0.0, а не 0. Параметр имеет тип f64, а Rust не превращает целое число в дробное втихую. Если у f64 нет дробной части, {} выводит его без .0 — поэтому ты видишь 32, а не 32.0.

Напиши функцию largest(a: i32, b: i32, c: i32) -> i32, которая возвращает наибольшее из трёх чисел. Проверь её на (3, 9, 4) и (-2, -8, -5). Подсказка: в Rust if — это выражение (см. If…else), поэтому цепочка if / else if / else может быть последней строкой функции.

Показать решение
fn largest(a: i32, b: i32, c: i32) -> i32 {
if a >= b && a >= c {
a
} else if b >= c {
b
} else {
c
}
}
fn main() {
println!("{}", largest(3, 9, 4));
println!("{}", largest(-2, -8, -5));
}

Вывод:

9
-2
▶ Попробуй сам

Ни одна ветка не заканчивается точкой с запятой. Каждая из них — выражение, вся цепочка if даёт одно из них, и оно становится результатом функции. >= вместо > гарантирует, что при равных числах значение всё равно вернётся.

  • Функции объявляются через fn, а вызываются как имя().
  • Параметры — это входные данные; у каждого должен быть тип: fn greet(name: &str).
  • Тип результата указывается через -> Тип.
  • Последнее выражение без точки с запятой — это возвращаемое значение.
  • return значение; тоже работает, но обычно его используют только для досрочного возврата.

Проверь себя

1. Нужно ли в Rust указывать тип каждого параметра функции?

2. Как указать тип результата функции?

3. Почему a + b (без точки с запятой) в конце функции становится её результатом?

4. Важно ли, объявлена функция выше или ниже места вызова (например, выше или ниже main)?

Результат: 0 / 4