在 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`,它接受一个类型为 `SGen<T>` 的参数 `_s`。
// 它被显式地给定了类型参数 `A`,但由于 `A` 没有被指定为 `gen_spec_t` 的泛型类型参数,所以它不是泛型函数。
fn gen_spec_t(_s: SGen<A>) {}

// 定义一个函数 `gen_spec_i32`,它接受一个类型为 `SGen<i32>` 的参数 `_s`。
// 它被显式地给定了类型参数 `i32`,这是一个具体类型。
// 因为 `i32` 不是泛型类型,所以这个函数也不是泛型函数。
fn gen_spec_i32(_s: SGen<i32>) {}

// 定义一个函数 `generic`,它接受一个类型为 `SGen<T>` 的参数 `_s`。
// 因为 `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`。

    // 为 `generic()` 显式指定类型参数 `char`。
    generic::<char>(SGen('a'));

    // 为 `generic()` 隐式指定类型参数 `char`。
    generic(SGen('c'));
}

总结

恭喜你!你已经完成了“函数”实验。你可以在 LabEx 中练习更多实验来提升你的技能。