Rust学习教程27 - 深入了解特征

本文深入探讨Rust的特征,包括关联类型、默认泛型类型参数、同名方法调用策略和特征定义中的特征约束。通过实例解释了如何在外部类型上实现特征,展示了newtype模式的应用,帮助开发者更好地理解和使用Rust的高级特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文节选自<<Rust语言圣经>>一书
欢迎大家加入Rust编程学院,一起学习交流:
QQ群:1009730433

深入了解特征

特征之于Rust更甚于接口之于其他语言,因此特征在Rust中很重要也相对较为复杂,我们决定把特征分为两篇进行介绍,第一篇在之前已经讲过,现在就是第二篇:关于特征的进阶篇,会讲述一些你不常用到但是该了解的特性。

关联类型

在方法一章中,我们将到了关联函数,但是实际上关联类型和关联函数并没有任何交集,虽然它们的名字有一半的交集。

关联类型是在特征定义的语句块中,申明一个自定义类型,这样就可以在特征的方法签名中使用该类型:

pub trait Iterator {
   
   
    type Item;

    fn next(&mut self) -> Option<Self::Item>;
}

以上是标准库中的迭代器特征Iterator,它有一个Item关联类型,用于替代遍历的值的类型。

同时,next方法也返回了一个Item类型,不过使用Option枚举进行了包裹,假如迭代器中的值是i32类型,那么调用next方法就将获取一个Option<i32>的值。

还记得Self吧?在之前的章节提到过, Self用来指代当前的特征实例 ,那么Self::Item就用来指代特征实例中具体的Item类型:

impl Iterator for Counter {
   
   
    type Item = u32;

    fn next(&mut self) -> Option<Self::Item> {
   
   
        // --snip--

在上述代码中,我们为Counter类型实现了Iterator特征,那么Self就是当前的Iterator特征对象,Item就是u32类型。

聪明的读者之所以聪明,因为你们喜欢联想和举一反三,同时你们也喜欢提问:为何不用泛型,例如如下代码

pub trait Iterator<Item> {
   
   
    fn next(&mut self) -> Option<Item>;
}

答案其实很简单,为了代码的可读性. 当你使用了泛型后,你需要在所有地方都这样写Iterator<Item>,而使用了关联类型,你只需要这样写Iterator,当类型定义复杂时,这种写法可以极大的增加可读性:

pub trait CacheableItem: Clone + Default + fmt::Debug + Decodable + Encodable {
   
   
  type Address: AsRef<[u8]> + Clone + fmt::Debug + Eq + Hash;
  fn is_null(&self) -> bool;
}

例如上面的代码,Address自然远比AsRef<[u8]> + Clone + fmt::Debug + Eq + Hash的要简单的多,而且含义清晰。

再例如,如果使用泛型,你将得到以下的代码:

trait Container<A,B> {
   
   
    fn contains(&self,a: A,b: B) -> bool;
}

fn difference<A,B,C>(container: &C) -> i32 where 
    C : Container<A,B> {
   
   ...}

而使用关联类型,将得到可读性好的多的代码:

trait Container{
   
   
    type A;
    type B;
    fn contains(&self, a: &Self::A
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值