Функции в 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Практика
Заголовок раздела «Практика»1. Из Цельсия в Фаренгейт
Заголовок раздела «1. Из Цельсия в Фаренгейт»Напиши функцию 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°F100°C — это 212°F37°C — это 98.6°FОбрати внимание: мы передаём 0.0, а не 0. Параметр имеет тип f64, а Rust не превращает целое число в дробное втихую. Если у f64 нет дробной части, {} выводит его без .0 — поэтому ты видишь 32, а не 32.0.
2. Наибольшее из трёх
Заголовок раздела «2. Наибольшее из трёх»Напиши функцию 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
Что почитать
Заголовок раздела «Что почитать»- Функции — книга «Язык программирования Rust»: официальная глава о параметрах, возвращаемых значениях, инструкциях и выражениях (перевод на русский).
- Инструкции и выражения — книга «Язык программирования Rust»: подробнее об идее, которая стоит за правилом точки с запятой (перевод на русский).
- Функции — Rust на примерах: запускаемые примеры, в том числе с досрочным
returnи функциями, которые ничего не возвращают (перевод на русский). - Functions — The Rust Reference (на английском): точные правила объявления функций — для тех, кому нужны все детали.
- The
fnkeyword — документация стандартной библиотеки (на английском): краткая сводка синтаксиса функций с примерами.