文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Rust中的关联类型总结

2023-05-18 17:44

关注

1. 关联类型简介

关联类型是定义通用 trait 的一种机制。它允许在 trait 中定义一个或多个占位符类型,这些类型将在 trait 的实现中具体化。这样可以增强代码的可读性,因为它可以将容器内部的类型移动到 trait 中作为输出类型。

例如,在下面的例子中有一个叫作 Graph 的 trait,它的节点和边使用了两个关联类型。

trait Graph {
    type N;
    type E;

    fn has_edge(&self, n1: &Self::N, n2: &Self::N) -> bool;
    fn edges(&self, n: &Self::N) -> Vec<Self::E>;
}

2. 关联类型与泛型的区别

关联类型和泛型都可以用来定义通用 trait,但它们之间存在一些区别。如果 trait 中包含泛型参数,那么可以对同一个目标类型多次 impl 此 trait,每次提供不同的泛型参数。而关联类型方式只允许对目标类型实现一次。如果 trait 中包含泛型参数,那么在具体方法调用的时候,必须加以类型标注以明确使用的是哪一个具体的实现。而关联类型方式具体调用时不需要标注类型(因为不存在模棱两可的情况)。

例如,假设你有一个叫做 MyNumeric 的类型。你可以在此类型上实现 From、From、From 等多种数据转换。但是对于关联类型,一个类型只能实现一个 trait 一次。

trait A<T> {
    fn f(t: T) -> T;
}

struct S {}

// 第一个实现: A<String>
impl A<String> for S {
    fn f(t: String) -> String {
        t
    }
}

// 第二个实现:A<i32>
impl A<i32> for S {
    fn f(t: i32) -> i32 {
        t
    }
}

trait A {
    type Item;
    fn f(t: Self::Item) -> Self::Item;
}

struct S {}

impl A for S {
    type Item = i32;
    fn f(t: Self::Item) -> Self::Item {
        t
    }
}

因此,在选择使用关联类型还是泛型时,需要根据具体情况进行判断。如果针对特定类型的 trait 有多个实现(例如 From),则使用泛型;否则使用关联类型(例如 Iterator 和 Deref)。

3. 关联类型的定义语法

关联类型的定义语法如下:

trait Contains {
    type A;
    type B;

    fn contains(&self, _: &Self::A, _: &Self::B) -> bool;
}

注意使用了 Contains trait 的函数就不需要写出 A 或 B 了:

// 不使用关联类型
fn difference<A, B, C>(container: &C) -> i32
where
    C: Contains<A, B>,
{
    ...
}

// 使用关联类型
fn difference<C: Contains>(container: &C) -> i32 {
    ...
}

4. 关联类型的使用场景

关联类型可以用于多种场景,例如在定义通用容器时,可以使用关联类型来表示容器内部的元素类型。这样可以增强代码的可读性,因为它可以将容器内部的类型移动到 trait 中作为输出类型。

struct Container(i32, i32);

trait Contains {
    type A;
    type B;

    fn contains(&self, _: &Self::A, _: &Self::B) -> bool;
    fn first(&self) -> i32;
    fn last(&self) -> i32;
}

impl Contains for Container {
    type A = i32;
    type B = i32;

    fn contains(&self, number_1: &i32, number_2: &i32) -> bool {
        (&self.0 == number_1) && (&self.1 == number_2)
    }

    fn first(&self) -> i32 {
        self.0
    }

    fn last(&self) -> i32 {
        self.1
    }
}

5. 关联类型与 trait 的配合使用

关联类型可以与 trait 配合使用,这样可以更好地表达代码中的抽象概念。例如,在下面的例子中,我们定义了一个叫做 Contains 的 trait,它包含两个关联类型 A 和 B。然后我们定义了一个叫做 Container 的结构体,并为它实现了 Contains trait。在实现过程中,我们指定了 A 和 B 的具体类型为 i32。

struct Container(i32, i32);

trait Contains {
    type A;
    type B;

    fn contains(&self, _: &Self::A, _: &Self::B) -> bool;
}

impl Contains for Container {
    type A = i32;
    type B = i32;

    fn contains(&self, number_1: &i32, number_2: &i32) -> bool {
        (&self.0 == number_1) && (&self.1 == number_2)
    }
}

6. 关联类型的优点

关联类型有许多优点。首先,它可以增强代码的可读性,因为它可以将容器内部的类型移动到 trait 中作为输出类型。其次,它可以减少代码的冗余,因为它允许我们在定义通用 trait 时省略一些不必要的泛型参数。此外,它还可以提高代码的灵活性,因为它允许我们在实现 trait 时指定关联类型的具体类型。

以上就是Rust中的关联类型总结的详细内容,更多关于Rust关联类型的资料请关注编程网其它相关文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯