$ sudo teach IT
Модуль 2 · Cargo.toml

Фичи (features)

Фичи позволяют включать части библиотеки по необходимости — компилируется только то, что реально нужно.

📖 Теория 🕐 ~20 минут
💡

Что такое фичи и зачем они нужны

Фичи (features) — это именованные флаги, которые включают или отключают части кода и зависимости. Главная цель — не компилировать то, что не используется.

Пример: библиотека tokio умеет делать очень много — TCP-сокеты, файловый ввод/вывод, таймеры, многопоточность. Если вам нужны только таймеры — зачем тянуть весь стек? Вы включаете только нужные фичи:

Cargo.toml
# Только то, что нужно:
tokio = { version = "1", features = ["time", "rt"] }

# Или всё сразу (удобно для экспериментов, хуже для размера бинарника):
tokio = { version = "1", features = ["full"] }
💡 Фичи используют и как потребители (вы включаете нужные фичи у зависимостей), и как авторы (вы определяете фичи для своей библиотеки). В этом уроке — оба сценария.
🔌

Включение фичей у зависимостей

Cargo.toml · Примеры реальных крейтов с фичами
[dependencies]
# serde: фича derive генерирует код через макрос #[derive(Serialize, Deserialize)]
serde = { version = "1", features = ["derive"] }

# reqwest: фича json добавляет .json() методы; blocking — синхронный API
reqwest = { version = "0.11", features = ["json", "blocking"] }

# tokio: rt = runtime, macros = #[tokio::main], fs = файловый ввод/вывод
tokio = { version = "1", features = ["rt", "macros", "fs"] }

# sqlx: выбираем только нужную СУБД и runtime
sqlx = { version = "0.7", features = ["postgres", "runtime-tokio-rustls"] }

Через cargo add:

Терминал
cargo add serde --features derive
cargo add tokio --features rt,macros,fs
cargo add reqwest --features json,blocking
⚠️ default features: большинство крейтов включают некоторые фичи по умолчанию. Отключить дефолтные фичи и выбрать только нужные: serde = {{ version = "1", default-features = false, features = ["derive"] }}
🏗️

Определение фичей в своём крейте

Секция [features] в Cargo.toml определяет какие фичи есть у вашей библиотеки. Каждая фича — это список других фичей или зависимостей, которые она включает:

Cargo.toml · Секция [features]
[features]
# Фичи включённые по умолчанию
default = ["json"]

# Фича "json" включает зависимость serde_json
json = ["dep:serde_json"]

# Фича "async" включает tokio
async = ["dep:tokio"]

# Фича "full" включает всё
full = ["json", "async"]

[dependencies]
serde = { version = "1", features = ["derive"] }
# Опциональные зависимости — подключаются только если включена фича
serde_json = { version = "1", optional = true }
tokio = { version = "1", features = ["full"], optional = true }

Сборка с конкретными фичами:

Терминал
cargo build --features "json,async"    # включить конкретные фичи
cargo build --features "full"          # включить фичу full
cargo build --no-default-features      # отключить default фичи
cargo build --no-default-features --features "async"  # только async
📌 Что важно запомнить
→ features = [...] включает части библиотеки — компилируется только нужное
→ default-features = false отключает дефолтные фичи крейта
→ optional = true делает зависимость подключаемой только через фичу
→ cargo build --features "..." включает фичи при сборке
→ dep:имя в [features] — ссылка на опциональную зависимость (синтаксис Rust 2021)

Тест

3 вопроса