这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

Rust的类型转换

Rust的类型转换

类型转换分为隐式类型转换(Implicit Type Conversion)和显式类型转换(Explicit Type Conversion):

  • 隐式类型转换: 由编译期或者解释器来完成,开发者并未参与,所以又称之为强制类型转换(Type Coercion)
  • 显式类型转换: 由开发者指定,即一般意义上的类型转换(Type cast)

1 - Deref解引用

Rust的Deref解引用

1.1 - [Rust编程之道笔记]Deref解引用

Rust编程之道一书 3.5.1 Deref解引用

3.5.1 解引用

rust 的隐式类型转换基本上只有自动解引用。自动解引用的目的主要是方便开发者使用智能指针。

自动解引用

自动解引用虽然是编译期来做的,但是自动解引用的行为可以由开发者来定义。

引用使用 & 操作符,而解引用使用 * 操作符。可以通过实现 Deref trait 来自定义解引用操作。

Deref 有一个特性是强制隐式转换,规则是这样:如果有一个类型T实现了 Deref<Target=U> ,则该类型T的引用(或者智能指针)在应用的时候会被自动转换为类型U。

Deref内部实现:

pub trait Deref {
    type Target: ?Sized;
    fn deref(&self) -> &Self::Target;
}

pub trait DerefMut : Deref {
    fn deref_mut(&mut self) -> &mut Self::Target;
}

DerefMut 和 Deref 类似,不过返回的是可变引用。

实现 Deref 的目的是简化编程,避免开发者自己手工转换。

手动解引用

如果某类型和其解引用目标类型中包含了相同的方法,编译期就不指导该用哪一个了,此时就需要手动解引用。

2 - as操作符

Rust的as操作符

2.1 - [Rust编程之道笔记]as操作符

Rust编程之道一书 3.5.2 as操作符

3.5.2 as操作符

as 操作符最常用的场景就是转换 rust 中的基本数据类型。

as 关键字不支持重载。

长类型转换为短类型的时候会被 截断处理。

无歧义完全限定语法

为结构体实现多个trait时,可能会出现同名的方法,使用 as 操作符可以帮助避免歧义。

fn main() {
    let s = S(1);
    // 当 trait 的静态函数来调用
    A::test(&s, 1);
    B::test(&s, 1);
    // 使用as操作符
    <S as A>::test(&s, 1);
    <S as B>::test(&s, 1);
}

类型和子类型相互转换

as转换可以用于类型和子类型之间的转换。

&'static str' 类型是 &'a str' 类型的子类型。两者的生命周期标记不同,'a'static 都是生命周期标记,其中 'a 是泛型标记,是 &str 的通用形式,而 'static 则是特指静态生命周期的 &str 字符串。

fn main() {
    let a: &'static str = "hello"; // 'static str
    let b: &str = a as &str; // &str
    let c: &'static str = b as &'static str; // 'static str
}

可以通过 as 操作符将 &'static str'&'a str' 相互转换。

3 - From

Rust的From

3.1 - [Rust编程之道笔记]From Trait

Rust编程之道一书 3.5.3 From Trait

3.5.3 From和Into

From 和 Into 是定义在 std::convert 模块中的trait,定义了 from 和 into 两个方法,互为反操作。

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

Into的默认规则:如果类型 U 实现了 From<T>,则 T 类型实例调用 into 方法时可以转换为类型 U。

这是 rust 标准库中有一个默认的实现:

impl<T, U> Into<U> for T where U: From<T>

tryFrom 和 tryInto trait

是 From 和 Into 的错误处理版本,因为转型转换是有可能发生错误的,所以需要进行错误处理时就可以用 TryFrom 和 TryInto。

AsRef 和 AsMut trait

将值分别转换为不可变引用和可变引用。

4 - Into

Rust的Into