Переменные
Объявление переменной
Синтаксис для объявления переменных в Rust выглядит так:
let имя_переменной: тип = значение;
Например:
#![allow(unused)]
fn main() {
let a: i32 = 5;
}
Если при объявлении переменной ей сразу присваивается значение, то тип можно опустить, так как компилятор выведет его автоматически:
#![allow(unused)]
fn main() {
let a = 5;
}
Также переменную можно сначала объявить, а значение присвоить ниже. При этом явное указание типа переменной так же не обязательно, так как компилятор сможет сопоставить объявление и последующую инициализацию.
#![allow(unused)]
fn main() {
let a;
a = 5;
}
Мутабельность
Tip
Мутабельность — англицизм (mutable), который означает “изменяемость”.
По умолчанию переменные в Rust немутабельны, то есть после того, как переменной присвоено значение, другое значение в неё записать компилятор уже не позволит.
Такая программа:
fn main() {
let a = 1;
a = 5;
}
вызовет ошибку компиляции:
error[E0384]: cannot assign twice to immutable variable `a`
--> main.rs:3:5
|
2 | let a = 1;
| - first assignment to `a`
3 | a = 5;
| ^^^^^ cannot assign twice to immutable variable
Для того, чтобы сделать переменную мутабельной, её нужно объявить с ключевым словом mut.
#![allow(unused)]
fn main() {
let mut a = 1;
a = 5;
}
Именование переменных
Имена переменных могут содержать только буквы (включая допустимые Unicode буквы), цифры и символ подчёркивания. При этом имя переменной не может начинаться с цифры. Ключевые слова Rust не могут быть использованы в качестве имени переменной.
#![allow(unused)]
fn main() {
let a = 1;
let b_x_5 = 2;
let таки_переменная = 3;
let 変数名 = 4;
}
В Rust для имен переменных принято использовать так называемую змеиную нотацию (Snake case):
- имена переменных должны начинаться со строчной буквы
- если имя переменной состоит из нескольких слов, то эти слова разделяются символом подчёркивания
Например:
#![allow(unused)]
fn main() {
let number = 1;
let some_number = 2;
let coordinate_2d_x = 2.11;
}
В случае необходимости использовать ключевое слово в качестве имени переменной (такое может понадобиться, например, для десериализации поля из бинарного формата), необходимо к имени переменной добавить суффикс r#:
#![allow(unused)]
fn main() {
let r#if = 5;
}
Константы
Кроме переменных, в Rust существуют и константы. В то время как переменные хранятся на стеке, константы хранятся, как правило, в сегменте кода.
Синтаксис объявления константы:
#![allow(unused)]
fn main() {
const ИМЯ: Тип = значение;
}
В отличие от переменных, для констант всегда необходимо явно указывать тип данных.
Имена констант должны состоять из заглавных букв, а в качестве разделителя использовать знак подчёркивания.
#![allow(unused)]
fn main() {
const PI: f32 = 3.14;
const ANONYMOUS_NAME: &str = "anonymous";
}
static
Статические переменные создаются в самом начале работы программы и существуют до её завершения, однако в отличие от констант, статические переменные:
- инициализируются уже во время работы программы, а не на этапе компиляции
- могут быть мутабельными
- могут содержать объекты, хранящие данные в куче
Статическая переменная объявляется при помощи ключевого слова static:
#![allow(unused)]
fn main() {
static ИМЯ: Тип = значение;
}
Статические переменные могут быть как глобальными, так и локальными для функции. Оба вида мы отдельно разберём в соответствующих главах.
Мутабельная статическая переменная — потенциально небезопасный ресурс, так как она может быть одновременно изменена из нескольких потоков. Поэтому работа с мутабельными статическими данными — unsafe операция, о чём мы еще поговорим позже.
Note
В то время как константы, как правило, хранятся в сегмента кода, статические переменные хранятся в сегменте bss (Block Started by Symbol) или в сегменте данных.
Префикс _
Компилятор выдает предупреждения (warning) для каждой неиспользуемой переменной — переменной, которая объявлена и, возможно, инициализирована, но при этом не используется в каком-либо выражении.
Если мы намеренно хотим иметь в коде такую переменную (например, как задел для будущей функциональности), то мы можем начать имя переменной со знака подчёркивания.
Например:
#![allow(unused)]
fn main() {
let _some_unused_variable = 5;
}
Компилятор не будет выдавать предупреждений о том, что такая переменная не используется.
“выброшенные” переменные
Если переменная состоит из одного только символа подчёркивания _, то она является “выброшенной” (discarded). Такая переменная семантически существует, однако обратиться к ней никак нельзя.
#![allow(unused)]
fn main() {
let _ = 5;
}
Один из сценариев применения “выброшенных” переменных — сознательное игнорирование результата функции. Мы рассмотрим этот пример в главе Result
Также мы увидим применение таких переменных в главах Деструктурирующее присваивание и Паттерн матчинг.