Узагальнені функції

Rust підтримує узагальнені типи, що дозволяє абстрагувати алгоритми або структури даних (наприклад, сортування або бінарне дерево) від типів, що використовуються або зберігаються.

/// Виберіть `even` або `odd` в залежності від значення `n`.
fn pick<T>(n: i32, even: T, odd: T) -> T {
    if n % 2 == 0 {
        even
    } else {
        odd
    }
}

fn main() {
    println!("вибраний номер: {:?}", pick(97, 222, 333));
    println!("вибрав рядок: {:?}", pick(28, "собака", "кіт"));
}
This slide should take about 5 minutes.
  • Rust визначає тип для T на основі типів аргументів та значення, що повертається.

  • У цьому прикладі ми використовуємо лише примітивні типи i32 та &str для T, але ми можемо використовувати будь-який тип, включаючи типи, визначені користувачем:

    struct Foo {
        val: u8,
    }
    
    pick(123, Foo { val: 7 }, Foo { val: 456 });
  • Це схоже на шаблони C++, але Rust частково компілює узагальнену функцію одразу, тому ця функція має бути валідною для всіх типів, що відповідають обмеженням. Наприклад, спробуйте модифікувати pick так, щоб вона повертала even + odd, якщо n == 0. Навіть якщо використовується лише екземпляр pick з цілими числами, Rust все одно вважатиме його невірним. C++ дозволить вам зробити це.

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