类型转换分为隐式类型转换(Implicit Type Conversion)和显式类型转换(Explicit Type Conversion):
- 隐式类型转换: 由编译期或者解释器来完成,开发者并未参与,所以又称之为强制类型转换(Type Coercion)
- 显式类型转换: 由开发者指定,即一般意义上的类型转换(Type cast)
类型转换分为隐式类型转换(Implicit Type Conversion)和显式类型转换(Explicit Type Conversion):
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 的目的是简化编程,避免开发者自己手工转换。
如果某类型和其解引用目标类型中包含了相同的方法,编译期就不指导该用哪一个了,此时就需要手动解引用。
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'
相互转换。
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>
是 From 和 Into 的错误处理版本,因为转型转换是有可能发生错误的,所以需要进行错误处理时就可以用 TryFrom 和 TryInto。
将值分别转换为不可变引用和可变引用。