# Создание и использование констант (const) и static в Rust

> Разница между const и static в языке Rust: как, зачем и когда использовать константы? Практический гайд с понятными примерами кода без лишней теории.

- **URL:** https://eagle2000.space/rust/rust-const/
- **Date:** 2025-05-24

- **Tags:** rust, dev

---## Введение
Константы `const` — один из базовых инструментов в Rust который как и переменные позволяет сохранять какие-либо данные в памяти. На первый взгляд они могут показаться похожими на переменные. Но есть несколько ключевых отличий, которые делают их полезными в определённых ситуациях. Давайте разберёмся, как их использовать, зачем они нужны и какие подводные камни могут нам встретиться.

## Отличие констант от переменных

Начнём с главного: константы **неизменяемы**. В отличие от `let`, которое хоть и может создавать неизменяемые переменные `let x = 5` но их всегда можно перезаписать через затенение `let x = 6` 

С константами такой трюк не пройдёт: значение констант фиксировано в момент компиляции и не может быть изменено.

Два важных момента:

1. **Область видимости**
    * Обычные переменные живут только внутри своего блока `{}` _скоупа_
    * Константы можно объявлять на уровне файла. Они будут доступны на протяжении всего кода в файле
2. **Когда вычисляется значение**
   * Переменные могут "принимать" значения во время выполнения `let user_input = read_line()`
   * Константы должны быть известны при компиляции - нельзя присвоить им результат вычислений в рантайме
  
## Как объявить константу?

Синтаксис объявления констант чрезвычайно прост, но имеет важные отличия от переменных.


### 💻 Работа с константами в Rust


#### Шаг 1

```rust
const MAX_CONNECTIONS: u32 = 100;
const SECONDS_IN_HOUR: u64 = 60 * 60; // Компилятор вычислит это выражение заранее!

fn main() {
    println!("Max: {}, Seconds: {}", MAX_CONNECTIONS, SECONDS_IN_HOUR);
}
```

**Объявление констант**
- Константы `const` объявляются с явным указанием типа.
- Значение константы вычисляется на этапе компиляции.


#### Шаг 2

```rust
// ?compile_fail
const FAST_LANG: &str = "Rust";

fn main() {
    println!("The {} language", FAST_LANG);
    let FAST_LANG = "Dart"; // ❌ Ошибка компиляции
}
```

**Константы нельзя переопределять/затенять**
- Затенение `let` запрещено для констант.
- Компилятор выдаст ошибку, защищая код от нежелательного переопределения глобальных значений.


{{< alert "fire"  >}}
🔥 Важные правила:

1. Старайтесь придерживаться именования `SCREAMING_SNAKE_CASE` (заглавные буквы и подчёркивание).
2. Нельзя изменять значение константы.
3. Нельзя затенять константу с помощью `let`.
4. Нужно обязательно указать тип после двоеточия (компилятор не выводит типы констант автоматически).
{{< /alert >}}

Зачем же так строго?
Компилятор Rust следует принципу "явное лучше неявного". Если бы константы можно было затенять - код становился бы менее предсказуемым и проще было бы допустить ошибку.

## Где используют константы?

### Знаменитые "магические числа"

Вместо:

```rust
if users.len() > 100 { ... }
```

Лучше написать: 


```rust
const MAX_USERS: usize = 100;
if users.len() > MAX_USERS { ... }
```

___

### Глобальные настройки

Например, лимиты или таймауты, коды ошибок:

```rust
const REQUEST_TIMEOUT: u64 = 5000; // 5 секунд
```

___

### Константные вычисления

Rust позволяет делать простые вычисления в const:

```rust
const SECONDS_IN_HOUR: u64 = 60 * 60; // Компилятор вычислит это заранее
```

___

## ⚠️ Что нельзя делать с константами

1. Нельзя брать значение из рантайма _например из пользовательского ввода_

```rust
let user_input = get_user_input();  
const INPUT: &str = user_input; // Ошибка!
```

Для таких случаев лучше использовать обычные переменные.

2. Нельзя изменять элементы внутри массива/коллекции

Если массив или коллекция объявлены как const их содержимое неизменяемо:

```rust
const NUMBERS: [i32; 3] = [1, 2, 3];
NUMBERS[0] = 5; // Ошибка!
```
___

## Итоги

Константы в Rust отлично подходят:
* Для неизменяемых значений известных заранее
* Для замены "магических чисел" в коде
* Для глобальных параметров которые не меняются


{{< alert icon="lightbulb" >}}
Не забывайте что:

- Нельзя изменять или затенять константы
- Значение должно вычисляться на этапе компиляции
- `SCREAMING_SNAKE_CASE`- правило наименования для констант
{{< /alert >}}

На последок совет: если не можете придумать название константы, подумайте к какой предметной области относится ее значение, а также читайте чужой код. Лучше если это будут исходники больших документированных проектов. Так вы получите насмотренность и зафиксируете для себя правильные наименования.
