Перейти до основного вмісту
Модуль 5 · Урок 1 із 29/14 у курсі~12 min
Модульні уроки (1/2)

Дженерики та функції

Узагальнення дозволяють писати гнучкий багаторазовий код, уникаючи дублювання логіки для різних типів даних. Замість визначення кількох функцій або структур для різних типів (наприклад, i32, f64 або String), ми можемо використовувати загальний параметр типу, який умовно позначається буквою T.

Компілятор Rust керує генериками за допомогою процесу, який називається мономорфізація: під час компіляції він створює копію загального коду для кожного конкретного типу, який фактично використовується. Це означає, що накладні витрати на продуктивність під час виконання нульові.


Загальні функції

Щоб визначити загальну функцію, ми вставляємо параметр типу <T> одразу після імені функції та перед списком аргументів:

Rust
fn print_value<T: std::fmt::Debug>(value: T) {
    println!("Value: {:?}", value);
}

У загальних функціях ми можемо використовувати загальний тип T як для типів аргументів, так і для типів повернення:

Rust
fn identity<T>(value: T) -> T {
    value
}

Загальні структури

Ми також можемо використовувати загальні параметри типу всередині структур (struct), щоб визначити гнучкі поля:

Rust
struct KeyValuePair<K, V> {
    key: K,
    value: V,
}

fn main() {
    let pair = KeyValuePair {
        key: String::from("age"),
        value: 30,
    };
}

У блоці impl для загальної структури ми повинні оголосити параметр типу <T> відразу після ключового слова impl, щоб вказати, що ми реалізуємо методи на загальній структурі:

Rust
struct Container<T> {
    value: T,
}

impl<T> Container<T> {
    fn new(value: T) -> Self {
        Container { value }
    }

    fn value(&self) -> &T {
        &self.value
    }
}

Спробуйте самі

Вправа 1: Точкова структура

вправи#rust.m5.l1.e1
Спроби: 0Завантаження…

Визначте загальну структуру під назвою Point<T> із двома полями: x типу T і y типу T. У основній функції створіть екземпляр змінної point, що містить Point із цілими значеннями x = 5 і y = 10, а потім надрукуйте значення point.x.

Завантаження редактора…
Показати підказку

Оголошіть структуру за допомогою `struct Point<T> { x: T, y: T }`. Створіть його екземпляр у main і використовуйте `point.x`, щоб надрукувати його.

Рішення доступне після 3 спроб

Вправа 2: Скасування кортежу за допомогою обміну

вправи#rust.m5.l1.e2
Спроби: 0Завантаження…

Напишіть загальну функцію під назвою swap<T>, яка приймає кортеж із двох елементів (T, T) і повертає новий кортеж (T, T) зі зміненими позиціями. У основній функції викличте функцію з кортежем (1, 2) і виведіть результат.

Завантаження редактора…
Показати підказку

Сигнатурою функції має бути `fn swap<T>(пара: (T, T)) -> (T, T)`. Повертає обернений кортеж за допомогою `(pair.1, pair.0)`.

Рішення доступне після 3 спроб

Вправа 3: Структура контейнера

вправи#rust.m5.l1.e3
Спроби: 0Завантаження…

Визначте загальну структуру Container<T>, що містить поле значення типу T. Реалізуйте загальний блок impl, щоб визначити новий метод, який приймає значення типу T і повертає екземпляр Container<T>.

Завантаження редактора…
Показати підказку

Використовуйте `impl<T> Container<T>`, щоб реалізувати пов’язаний метод `fn new(value: T) -> Self { Container { value } }`.

Рішення доступне після 3 спроб