Please enable Javascript to view the contents

[Rust Std Trait] 类型转换 trait 初见(一)

 ·  ☕ 2 分钟

前言

    虽然在 Rust 中提供了用于做基本类型转换的关键字 as,但是自定义类型也有类型转换的需求,所以 Rust 标准库为我们提供了一系列 trait 来解决这个问题。本篇文章以最短的篇幅概括 类型转换相关 trait 的主要知识点。

AsRef/AsMut

    这两个 trait 主要负责从 A 类型的 &self/&mut self 转换成 B 类型的 &/&mut:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
pub trait AsRef<T> 
where
    T: ?Sized, 
{
    pub fn as_ref(&self) -> &T;
}

pub trait AsMut<T> 
where
    T: ?Sized, 
{
    pub fn as_mut(&mut self) -> &mut T;
}

需要注意的点:

  • 这两个都是用来做那种比较简单的转换,类似直接返回的那种。如果在类型转换消耗很大应该考虑使用 From 或者自定义函数
  • 这两个 trait 做的类型转换都不能失败。如果类型转换存在失败的可能需要自己写自定义函数
  • AsRef 和 Borrow 的区别还没真正理解,先挖个坑,等研究 HashMap 的时候再填
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
extern crate hello_rust;

struct Name(&'static str);

fn show_name<T: AsRef<Name>>(item: T) {
    println!("name is :{}", item.as_ref().0);
}

struct Bus {
    vehicle_name: Name,
}

impl AsRef<Name> for Bus {
    fn as_ref(&self) -> &Name {
        &self.vehicle_name
    }
}

struct Apple {
    fruit_name: Name,
}

impl AsRef<Name> for Apple {
    fn as_ref(&self) -> &Name {
        &self.fruit_name
    }
}

fn main() {
    let bus = Bus {
        vehicle_name: Name("bus"),
    };

    let apple = Apple {
        fruit_name: Name("apple"),
    };

    show_name(bus);
    show_name(apple);
}

From/Into

    这两个 trait 主要处理 A 和 B 值类型之间的相互转换。标准库中还存在他俩的可失败版本 TryFrom/TryInto。

1
2
3
4
5
6
7
8
pub trait From<T> {
    #[lang = "from"]
    pub fn from(T) -> Self;
}

pub trait Into<T> {
    pub fn into(self) -> T;
}

需要注意的点:

  • 因为实现 From 时标准库会有一个 Into 的预制实现。然而反过来并不是,所以我们应该优先选择实现 From trait
  • 声明时优先使用 Into,因为 From 会自动实现 Into 而 Into 并不会自动实现 From
  • From/Into 都不允许失败,如果有可能失败可以选择 TryFrom/TryInto
  • From 在 Rust 的错误处理中应用广泛
分享

saberuster
作者
saberuster
一个喜欢编程和折腾的追风少年