Открыть сервис

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 →