初学者,若内容有任何问题,欢迎大佬在评论区纠正补充
From
是 Rust 标准库提供的 trait 提供了一种非常简单的机制来在多种类型之间进行转换
pub trait From<T>: Sized {
/// Converts to this type from the input type.
#[rustc_diagnostic_item = "from_fn"]
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn from(value: T) -> Self;
}
当然一个很简单的例子:我们可以使用 String::from 将 str 转换为 String
fn main() {
let str = "Hello Rust";
let string = String::from(str);
println!("{string}")
}
因为官方已经默认为 String 实现了 From trait 👇
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")]
impl From<&str> for String {
/// Converts a `&str` into a [`String`].
///
/// The result is allocated on the heap.
#[inline]
fn from(s: &str) -> String {
s.to_owned()
}
}
所以我们可以自己为某些类型实现 From trait 来定义自己的类型转换
// 需求 将 i32 转为 Count
// 首先定义struct
#[derive(Debug)]
struct Count {
value: i32,
}
// 为 Count 手动实现 From trait
impl From<i32> for Count {
fn from(value: i32) -> Self {
Count { value }
}
}
fn main() {
// 如何使用
let count = Count::from(18);
println!("{count:?}") // Count { value: 18 }
}
Into
Into 的作用和 from 类似,也可以实现类型转换
不过呢,编译器通常无法推断出转换完的类型,则需要自己手动标注 ❗❗
// 需求 将 i32 转为 Count
// 首先定义struct
#[derive(Debug)]
struct Count {
value: i32,
}
// 为 i32 手动实现 Into trait
impl Into<Count> for i32 {
fn into(self) -> Count {
Count { value: self }
}
}
fn main() {
// 如何使用
let c = 32;
// 需要手动标注类型
let c: Count = c.into();
println!("{:?}", c) // Count { value: 32 }
}
From 和 Into 可以互换
已经为 Count 实现了 From trait,则对应的 i32 类型,就可以调用 into,无需再手动实现
反之如果为某个类型实现了 Into trait 则无法自动活动 from 方法 ❗❗
// 需求 将 i32 转为 Count
// 首先定义struct
#[derive(Debug)]
struct Count {
value: i32,
}
// 为 Count 手动实现 From trait
impl From<i32> for Count {
fn from(value: i32) -> Self {
Count { value }
}
}
fn main() {
// 如何使用
let count = Count::from(18);
println!("{count:?}"); // Count { value: 18 }
let num = 19;
let count2: Count = num.into();
println!("{count2:?}") // Count { value: 19 }
}
总结一下
方向性差异: From trait 定义了如何从其他类型转换到实现 From trait 的类型。而 Into trait 定义了如何将实现 Into trait 的类型转换到其他类型。