探索 Rust 泛型功能

RustRustBeginner
立即练习

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

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在本实验中,我们将探索泛型的主题,泛型涉及将类型和功能进行泛化,以处理更广泛的情况,减少代码重复。Rust 中泛型的语法涉及使用尖括号指定类型参数,例如 <T>。通过使用泛型,我们可以创建能够接受任何类型参数的泛型函数。此外,我们还可以定义能够与不同具体类型一起工作的泛型类型。

注意:如果实验未指定文件名,你可以使用任何你想要的文件名。例如,你可以使用 main.rs,并通过 rustc main.rs &&./main 进行编译和运行。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL rust(("Rust")) -.-> rust/DataTypesGroup(["Data Types"]) rust(("Rust")) -.-> rust/FunctionsandClosuresGroup(["Functions and Closures"]) rust(("Rust")) -.-> rust/MemorySafetyandManagementGroup(["Memory Safety and Management"]) rust(("Rust")) -.-> rust/AdvancedTopicsGroup(["Advanced Topics"]) rust(("Rust")) -.-> rust/BasicConceptsGroup(["Basic Concepts"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("Variable Declarations") rust/DataTypesGroup -.-> rust/integer_types("Integer Types") rust/DataTypesGroup -.-> rust/type_casting("Type Conversion and Casting") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("Function Syntax") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("Expressions and Statements") rust/MemorySafetyandManagementGroup -.-> rust/lifetime_specifiers("Lifetime Specifiers") rust/AdvancedTopicsGroup -.-> rust/operator_overloading("Traits for Operator Overloading") subgraph Lab Skills rust/variable_declarations -.-> lab-99344{{"探索 Rust 泛型功能"}} rust/integer_types -.-> lab-99344{{"探索 Rust 泛型功能"}} rust/type_casting -.-> lab-99344{{"探索 Rust 泛型功能"}} rust/function_syntax -.-> lab-99344{{"探索 Rust 泛型功能"}} rust/expressions_statements -.-> lab-99344{{"探索 Rust 泛型功能"}} rust/lifetime_specifiers -.-> lab-99344{{"探索 Rust 泛型功能"}} rust/operator_overloading -.-> lab-99344{{"探索 Rust 泛型功能"}} end

泛型

“泛型”是将类型和功能泛化到更广泛情况的主题。这在许多方面对于减少代码重复极为有用,但可能需要相当复杂的语法。也就是说,要实现泛型,需要格外注意指定泛型类型在哪些类型上实际被视为有效。泛型最简单和最常见的用途是用于类型参数。

通过使用尖括号和大写字母将类型参数指定为泛型,通常表示为 <T>。在 Rust 中,“泛型”还描述任何接受一个或多个泛型类型参数 <T> 的东西。任何被指定为泛型类型参数的类型都是泛型的,而其他所有类型都是具体的(非泛型的)。

例如,定义一个名为 foo 的“泛型函数”,它接受任何类型的参数 T

fn foo<T>(arg: T) {... }

因为 T 使用 <T> 被指定为泛型类型参数,所以当它在这里用作 (arg: T) 时被视为泛型。即使 T 之前被定义为一个 struct,情况也是如此。

这个示例展示了一些实际使用的语法:

// 一个具体类型 `A`。
struct A;

// 在定义类型 `Single` 时,`A` 的首次使用之前没有 `<A>`。
// 因此,`Single` 是一个具体类型,并且 `A` 如上所定义。
struct Single(A);
//            ^ 这里是 `Single` 对类型 `A` 的首次使用。

// 这里,`<T>` 在 `T` 的首次使用之前,所以 `SingleGen` 是一个泛型类型。
// 因为类型参数 `T` 是泛型的,它可以是任何东西,包括
// 顶部定义的具体类型 `A`。
struct SingleGen<T>(T);

fn main() {
    // `Single` 是具体的,并且明确使用 `A`。
    let _s = Single(A);

    // 创建一个类型为 `SingleGen<char>` 的变量 `_char`
    // 并给它赋值 `SingleGen('a')`。
    // 这里,`SingleGen` 有一个明确指定的类型参数。
    let _char: SingleGen<char> = SingleGen('a');

    // `SingleGen` 也可以隐式指定类型参数:
    let _t    = SingleGen(A); // 使用顶部定义的 `A`。
    let _i32  = SingleGen(6); // 使用 `i32`。
    let _char = SingleGen('a'); // 使用 `char`。
}

总结

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