【Rust中级教程】1.16. 泛型trait:泛型(类型参数)trait、关联类型trait

news/2025/2/22 23:55:21/

喜欢的话别忘了点赞、收藏加关注哦(加关注即可阅读全文),对接下来的教程有兴趣的可以关注专栏。谢谢喵!(=・ω・=)

这篇文章以概念性的和建议性的文字偏多,需要你对泛型类型参数和关联类型有一定了解,如果没有了解的请先看【Rust自学】19.2.1. 在trait定义中使用关联类型来指定占位类型

请添加图片描述

1.16.1. trait的泛型方式

trait的泛型方式有两种:

  • 泛型类型参数。例:trait Foo<T>
  • 关联类型。例:trait Foo{type Bar;}

两者的区别在于:

  • 使用关联类型这种形式的效果就是对于指定类型的trait只有一个实现
  • 使用泛型参数类型则可以有多个实现

这里有一个简单的建议:可以的话尽量使用关联类型。

1.16.2. 泛型(类型参数)trait

泛型trait要求必须指定所有的泛型类型参数,并重复写这些参数的约束(bounds)

这么写维护起来会难一些。比如说如果添加泛型类型参数到某个trait,该trait的所有实现者都必须更新代码。

这种形式还可能会导致针对给定的类型,一个trait有多重实现的问题。编译器会更难推断你想要的到底是trait的哪个实例。有时候不得不调用类似FromIterator::<u32>::from_iter这样可以消除歧义的函数。

这个特性有的时候也会是一个优点,例如:

  • impl PatialEq<BookFormat> for Book,其中BookFormat就可以是不同的类型
  • 可以同时实现FromIterator<T>FromIterator<&T> where T:Clone

1.16.3. 关联类型trait

我们以一段代码为例:

rust">trait Contains {type A;type B;//Updates syntax to refer to these new types genericallyfn contains(&self, _: &Self::A, _: &Self::B) -> bool;
}

使用关联类型:

  • 编译器只需要知道实现trait的类型
  • 约束(bound) 可以完全位于trait本身,不必重复使用
  • 未来再添加关联类型也不影响用户使用
  • 具体的类型会决定trait内关联类型的类型,无需使用消除歧义的函数,看个例子:
rust">impl Contains for Container {// Specify what types `A` and `B` are. If the `input` type// is `Container(i32, i32)`, the `output` types are determined// as `i32` and `i32`.type A = i32;type B = i32;// `&Self::A` and `&Self::B` are also valid here.fn contains(&self, number_1: &i32, number_2: &i32) -> bool {(&self.0 == number_1) && (&self.1 == number_2)}// Grab the first number.fn first(&self) -> i32 { self.0 }// Grab the last number.fn last(&self) -> i32 { self.1 }
}
  • 这个例子写了为Container类型实现Contains trait
  • Container类型的Contains trait中的关联类型通过type A = i32;type B = i32;这两行代码决定

不可以对多个目标(Target)类型来实现Deref trait

看一下Deref trait的源代码:

rust">pub trait Deref {type Target: ?Sized;fn deref(&self) -> &self::Target;
}
  • type Target: ?Sized;中的Target就是我们说的目标(Target)类型

我们随便写一个Deref trait的实现来说明一下:

rust">use std::ops::Deref;struct Wrapper {value: String,
}impl Deref for Wrapper {type Target = String;fn deref(&self) -> &Self::Target {&self.value}
}

上面代码中,Wrapper只能解引用为String。但如果你想让Wrapper同时解引用为Stringstr,Rust不允许你再实现Deref,因为Target只能有一个具体类型。

也就是说,这么写是非法的:

rust">use std::ops::Deref;struct Wrapper {value: String,
}// 第一次实现 Deref,Target = String
impl Deref for Wrapper {type Target = String;fn deref(&self) -> &Self::Target {&self.value}
}// 这是非法的,Rust 不允许对同一个类型 `Wrapper` 进行第二次 `Deref` 实现
impl Deref for Wrapper {type Target = str;  // 冲突,Rust 不能推断哪个 `Target` 生效fn deref(&self) -> &Self::Target {&self.value}
}

不可以使用多个Item来实现Iterator trait

其原因与不可以对多个目标(Target)类型来实现Deref trait一样,主要涉及关联类型的唯一性Rust 编译器的推断规则


http://www.ppmy.cn/news/1574278.html

相关文章

【数据库系统概论】第第12章 并发控制

12.1 并发控制概述 并发控制是指数据库管理系统&#xff08;DBMS&#xff09;通过控制多个事务同时执行&#xff0c;保证数据的一致性和隔离性&#xff0c;避免事务间的相互干扰。 事务串行执行不能充分利用系统资源 并发执行的优点&#xff1a;能够减少处理机的空闲 时间&a…

【Gee】7天用 Go 从零实现 Web 框架 Gee

7天用 Go 从零实现 Web 框架 Gee 设计一个框架 在设计一个框架之前&#xff0c;我们需要回答框架核心为我们解决了什么问题。只有理解了这一点&#xff0c;才能想明白我们需要在框架当中实现什么功能。 首先我们来看一下标准库 net/http 如何处理一个请求&#xff1a; func…

计算机视觉(CV)

计算机视觉&#xff08;CV&#xff09;技术是人工智能&#xff08;AI&#xff09;领域的一个重要分支&#xff0c;其优势和挑战如下所示&#xff1a; 优势&#xff1a; 自动化处理&#xff1a;CV 技术可以自动处理大量图像和视频数据&#xff0c;实现高效的信息提取和分析&am…

百问网(100ask)的IMX6ULL开发板的以太网控制器(MAC)与物理层(PHY)芯片(LAN8720A)连接的原理图分析(包含各引脚说明以及工作原理)

前言 本博文承接博文 https://blog.csdn.net/wenhao_ir/article/details/145663029 。 本博文和博文 https://blog.csdn.net/wenhao_ir/article/details/145663029 的目录是找出百问网(100ask)的IMX6ULL开发板与NXP官方提供的公板MCIMX6ULL-EVK(imx6ull14x14evk)在以太网硬件…

DeepSeek私有化专家 | 云轴科技ZStack入选IDC中国生成式AI市场概览

DeepSeek 火爆全球AI生态圈&#xff0c;并引发企业用户大量私有化部署需求。 国际数据公司IDC近日发文《DeepSeek爆火的背后&#xff0c;大模型/生成式AI市场生态潜在影响引人关注》&#xff0c;认为中国市场DeepSeekAI模型的推出在大模型/生成式AI市场上引起了轰动&#xff0c…

Android TabLayout 实现随意控制item之间的间距

效果 红色标注是不同的间距。 实现方式 1、xml中定义 <com.google.android.material.tabs.TabLayoutandroid:id"id/tab_layout"android:layout_width"wrap_content"app:tabIndicatorColor"color/color_FF00B2E3"app:tabBackground"a…

提升接口性能之缓存

缓存策略: 从本地到分布式, 再到 HTTP 缓存的全面解析 引言 在当今的软件开发中, 缓存技术扮演着至关重要的角色. 它能够显著提升系统性能, 降低数据库负载, 提高用户体验. 本文将详细介绍三种常见的缓存策略: 本地缓存, 分布式缓存以及 HTTP 缓存, 并探讨如何在实际应用中合…

DeepSeek 点燃关键技术突破的科技引擎,驶向未来新航道

本文将深入探讨 DeepSeek AI 大模型的技术原理、应用场景&#xff0c;并结合丰富的代码示例&#xff0c;详细阐述如何利用该模型实现关键技术的突破。 目录 一、本篇背景&#xff1a; 二、DeepSeek AI 大模型概述&#xff1a; 2.1 发展背景与意义&#xff1a; 2.2 核心技术…