Определение обобщенных функций в Rust

Beginner

This tutorial is from open-source community. Access the source code

Введение

В этом лабе вы научитесь определять обобщенные функции в Rust. Чтобы сделать функцию обобщенной, вам нужно добавить тип T с <T>. Иногда вам может потребоваться явно указать параметры типа при вызове обобщенной функции, что можно сделать с помощью синтаксиса fun::<A, B,...>(). Код, предоставленный в этом документе, демонстрирует использование обобщенных функций в Rust и включает примеры функций, которые являются как обобщенными, так и не обобщенными.

Примечание: Если в лабе не указано имя файла, вы можете использовать любое имя файла, которое хотите. Например, вы можете использовать main.rs, скомпилировать и запустить его с помощью rustc main.rs &&./main.

Функции

Те же правила можно применить к функциям: тип T становится обобщенным, если перед ним стоит <T>.

При использовании обобщенных функций иногда требуется явно указать параметры типа. Это может быть необходимо, если функция вызывается с обобщенным типом возврата, или если компилятору недостаточно информации для вывода необходимых параметров типа.

Вызов функции с явно указанными параметрами типа выглядит так: fun::<A, B,...>().

struct A;          // Конкретный тип `A`.
struct S(A);       // Конкретный тип `S`.
struct SGen<T>(T); // Обобщенный тип `SGen`.

// Следующие функции все получают владение переменной, переданной в них,
// и сразу же вышли из области видимости, освобождая переменную.

// Определите функцию `reg_fn`, которая принимает аргумент `_s` типа `S`.
// Это не имеет `<T>`, поэтому это не обобщенная функция.
fn reg_fn(_s: S) {}

// Определите функцию `gen_spec_t`, которая принимает аргумент `_s` типа `SGen<T>`.
// Ей явно задан параметр типа `A`, но поскольку `A` не задан как обобщенный
// параметр типа для `gen_spec_t`, это не обобщенная функция.
fn gen_spec_t(_s: SGen<A>) {}

// Определите функцию `gen_spec_i32`, которая принимает аргумент `_s` типа `SGen<i32>`.
// Ей явно задан параметр типа `i32`, который является конкретным типом.
// Поскольку `i32` не является обобщенным типом, эта функция также не является
// обобщенной.
fn gen_spec_i32(_s: SGen<i32>) {}

// Определите функцию `generic`, которая принимает аргумент `_s` типа `SGen<T>`.
// Поскольку `SGen<T>` передано с `<T>`, эта функция является обобщенной по `T`.
fn generic<T>(_s: SGen<T>) {}

fn main() {
    // Использование не обобщенных функций
    reg_fn(S(A));          // Конкретный тип.
    gen_spec_t(SGen(A));   // Неявно заданный параметр типа `A`.
    gen_spec_i32(SGen(6)); // Неявно заданный параметр типа `i32`.

    // Явно задан параметр типа `char` для `generic()`.
    generic::<char>(SGen('a'));

    // Неявно задан параметр типа `char` для `generic()`.
    generic(SGen('c'));
}

Резюме

Поздравляем! Вы завершили лабу по Функциям. Вы можете практиковаться в более лабах в LabEx, чтобы улучшить свои навыки.