const (Rust)
const — это ключевое слово в языке программирования Rust, используемое для объявления констант — значений, которые вычисляются на этапе компиляции и остаются неизменными на протяжении всего времени выполнения программы. В отличие от переменных, объявленных с помощью let, константы не могут быть изменены или переопределены. Они всегда должны иметь явно указанный тип и не могут быть результатом вычислений, выполняемых во время исполнения (runtime), за исключением константных функций и выражений, которые компилятор способен вычислить статически.
Определение и синтаксис
Константа в Rust объявляется с помощью ключевого слова const, за которым следует имя константы, двоеточие, тип и присваиваемое значение. Имена констант принято записывать в верхнем регистре с подчёркиваниями между словами (SCREAMING_SNAKE_CASE), хотя это не является строгим требованием языка.
``rust const MAX_POINTS: u32 = 100_000; ``
В этом примере объявляется константа MAX_POINTS типа u32 со значением 100 000. Тип обязателен: компилятор не выводит его автоматически, как для let.
Константы могут быть объявлены в любой области видимости, включая глобальную (вне функций), что делает их доступными из любой части программы. Они также могут быть объявлены внутри функций, структур или модулей.
Отличия от let и static
Rust предоставляет несколько способов хранения неизменяемых значений, и const занимает среди них особое место.
const vs let
- Вычисление:
constвычисляется на этапе компиляции;let— во время выполнения. - Тип:
constтребует явного указания типа;letможет выводить тип автоматически. - Изменяемость:
constвсегда неизменяема;letпо умолчанию неизменяема, но может быть изменена с помощьюmut. - Область видимости:
constможет быть глобальной;let— только локальной (внутри блока, функции или выражения). - Встраивание: При использовании
constкомпилятор встраивает значение в каждое место обращения, что может привести к дублированию кода.letсоздаёт переменную, хранящуюся в памяти (стеке или куче).
const vs static
static также объявляет глобальную неизменяемую переменную, но с ключевыми отличиями:
- Адрес в памяти:
staticимеет фиксированный адрес в памяти;constне имеет адреса, так как встраивается. - Внутренняя изменяемость:
staticможет быть объявлен сmut(изменяемый статик), что требуетunsafeдля доступа.constне может быть изменяемым. - Время жизни:
staticимеет время жизни'static, что означает, что он существует всё время работы программы.constне имеет времени жизни в традиционном смысле, так как не является переменной. - Использование в шаблонах:
constможно использовать в сопоставлении с образцом (pattern matching);static— нет.
``rust const PI: f64 = 3.14159; static GREETING: &str = "Hello, world!"; ``
Константные выражения и функции
Значение константы должно быть константным выражением — то есть выражением, которое компилятор может вычислить на этапе компиляции. Это включает:
- Литералы (числа, строки, булевы значения).
- Арифметические операции над литералами.
- Вызовы константных функций (объявленных с ключевым словом
const fn). - Доступ к другим константам.
- Некоторые операции над массивами и кортежами.
const fn
Функции, помеченные как const fn, могут быть вызваны в константных выражениях. Они имеют ограниченные возможности: не могут использовать циклы (кроме for над диапазонами), условные операторы (кроме if и match с константными условиями), а также не могут вызывать неконстантные функции. Начиная с Rust 1.46, const fn поддерживает if, match и циклы, но с ограничениями.
```rust const fn factorial(n: u32) -> u32 { match n { 0 => 1, _ => n * factorial(n - 1), } }
const FACT_10: u32 = factorial(10); // 3 628 800 ```
Применение
Константы широко используются в Rust для:
- Магических чисел: Замена числовых литералов осмысленными именами (например,
MAX_BUFFER_SIZE,DEFAULT_TIMEOUT). - Конфигурационных параметров: Значения, которые не меняются во время работы программы (например, размеры массивов, порты по умолчанию).
- Математических и физических констант:
PI,E,SPEED_OF_LIGHT. - Объявления статических данных: Строки, массивы, структуры, которые должны быть доступны глобально.
- Сопоставления с образцом: Константы можно использовать в
matchдля сравнения значений.
```rust const HTTP_OK: u16 = 200; const HTTP_NOT_FOUND: u16 = 404;
fn handle_status(code: u16) -> &'static str { match code { HTTP_OK => "OK", HTTP_NOT_FOUND => "Not Found", _ => "Unknown", } } ```
Ограничения и особенности
- Тип должен быть известен: Компилятор не выводит тип константы, поэтому его необходимо указывать явно.
- Нет динамической памяти: Константы не могут содержать значения, требующие выделения памяти в куче (например,
VecилиString), если только они не являются константными ссылками на статические данные. - Встраивание: Из-за встраивания констант каждое их использование приводит к копированию значения. Для больших массивов или структур это может увеличить размер бинарного файла. В таких случаях предпочтительнее использовать
static. - Нестабильные возможности: Некоторые возможности
const fnи константных выражений (например,constв трейтах) могут быть доступны только в nightly-версии компилятора.
Примеры использования
Константы для конфигурации
``rust const APP_NAME: &str = "MyApp"; const VERSION: u32 = 1; const DEBUG_MODE: bool = false; ``
Константы в структурах
Константы могут быть объявлены внутри impl-блоков структур или перечислений:
```rust struct Circle { radius: f64, }
impl Circle { const PI: f64 = 3.141592653589793;
fn area(&self) -> f64 { Self::PI self.radius self.radius } } ```
Константы для сопоставления с образцом
```rust const NORTH: u8 = 0; const EAST: u8 = 1; const SOUTH: u8 = 2; const WEST: u8 = 3;
fn direction_name(dir: u8) -> &'static str { match dir { NORTH => "North", EAST => "East", SOUTH => "South", WEST => "West", _ => "Unknown", } } ```
Сравнение с другими языками
В C и C++ аналогом const в Rust является #define (макрос препроцессора) или const-квалификатор, но с отличиями: макросы не имеют типов и не проверяются компилятором, а const в C/C++ — это переменная, которая может быть изменена через указатель. В Rust const гарантирует неизменяемость и типобезопасность.
В языках, таких как Java или C#, const в Rust ближе к static final (Java) или const (C#), но с более строгими правилами вычисления на этапе компиляции.
Источники
- The Rust Programming Language, 2nd Edition (Steve Klabnik, Carol Nichols) — глава 3.1 «Variables and Mutability», глава 19.1 «Unsafe Rust».
- Rust Reference — раздел «Items» > «Constant items».
- Документация Rust по ключевому слову
const(rustc book). - Статья «Const vs Static in Rust» на официальном блоге Rust (2015).
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →