Определение переменных и вызов функций в Rust
Взглянем на код:
fn main() {
let a = 10;
let b: i32 = 20;
let c = 30i32;
let d = 30_i32;
let e = add(add(a, b), add(c, d));
println!("(a + b) + (c + d) = {}", e);
}
fn add(i: i32, j: i32) -> i32 {
i + j;
}
Определение функции начинается с ключевого слова fn
. Точка входа в Rust-программы - это функция main. Она не получает никаких аргументов и не возвращает никаких значений.
В следующих строках let используется для привязки переменной. По умолчанию переменные неизменяемые, то есть предназначены только для чтения, а не для чтения-записи.
Также можно указывать конкретный тип данных разными способами:
Через двоеточие
Числовые литералы могут включать аннотации типов
В последней строке вызывается макрос println!
для вывода текста.
В строках используются двойные, а не одинарные кавычки, а для символах используются одинарные.
И наконец, функция add имеет аргументы с указанными типами данных и возвращает нужный тип данных. Как вы видите, возврат значения происходит автоматически, для этого не используются ключевые слова по типу return
.
Поговорим о создании переменных. В Rust они бывают мутабельными (mutable) или немутабельными (unmutable), то есть изменяемые и неизменяемые. Неизменяемые переменные можно сравнить с константами.
Разберем пример:
fn main() {
let a = 10;
a = 15;
}
Если мы скомпилируем данную программу, то получим ошибку:
error[E0384]: cannot assign twice to immutable variable `a`
--> src\main.rs:25:5
|
24 | let a = 10;
| - first assignment to `a`
25 | a = 2;
| ^^^^^ cannot assign twice to immutable variable
|
help: consider making this binding mutable
|
24 | let mut a = 10;
| +++
Т.к. все переменные в rust изначально неизменяемые, то мы не можем изменить переменную. Компилятор нам подсказывает, что для изменения значений надо добавить ключевое слово mut.
Добавим:
fn main() {
let mut a = 10;
a = 15;
println!(a);
}
Программа успешно скомпилируется и мы получим 15.
Но также существуют константы. Подобно неизменяемым переменным, константы — это значения, которые связаны с именем и не могут изменяться, но между константами и переменными есть несколько различий. Во-первых, нельзя использовать mut
с константами. Константы не просто неизменяемы по умолчанию — они неизменяемы всегда. Для объявления констант используется ключевое слово const
вместо let
, а также тип значения должен быть указан в аннотации.
fn main() {
const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3;
}
Имя константы - THREE_HOURS_IN_SECONDS
, а её значение устанавливается как результат умножения 60 (количество секунд в минуте) на 60 (количество минут в часе) на 3 (количество часов, которые нужно посчитать в этой программе). Соглашение Rust для именования констант требует использования всех заглавных букв с подчёркиванием между словами. Компилятор может вычислять ограниченный набор операций во время компиляции, позволяющий записать это значение более понятным и простым для проверки способом, чем установка этой константы в значение 10 800.
Константы существуют в течение всего времени работы программы в пределах области, в которой они были объявлены. Это свойство делает константы полезными для значений в домене вашего приложения, о которых могут знать несколько частей программы, например, максимальное количество очков, которое может заработать любой игрок в игре, или скорость света.
Еще момент - в листингах выше мы не декларировали тип данных переменных.
Вообще, типизация в Rust несет полу строгий характер. Разработчик может не указывать тип данных. Это может укоротить код, если сама программа небольшая. Но всегда рекомендуется описывать тип данных, иначе могут возникнуть ошибки. Например:
fn main() {
let mut a = 10;
a = "hello"; // возникнет ошибка
}
Мы не можем поменять тип данных, которые хранятся в переменной. Обычно типы данных указывают так:
fn main() {
let mut a: i32 = 10;
a = 15;
}