AsRef 和 AsMut
用于类型间廉价引用转换的Trait,为不同类型的引用提供了一种统一的访问方式
AsRef
- pub trait AsRef<T: ?Sized> {
- fn as_ref(&self) -> &T;
- }
复制代码 作用: 将某个类型的不可变引用转换为目标类型T的不可变引用
表示当前类型可以视为某种T类型的引用,转换过程无副作用,直接取内部引用,不拷贝数据
常用于函数参数中接受多种类型输入, 例如同时兼容string和&str- // 接受所有能转换为 &str 的类型
- fn print_length(s: impl AsRef<str>) {
- println!("Length = {}", s.as_ref().len());
- }
- fn main() {
- print_length("hello"); // &str
- print_length(String::from("world")); // String
- }
复制代码 标准库实现举例
String: AsRef:String 可以转换为 &str
Vec: AsRef:Vec 可以转换为切片 &[T]
PathBuf: AsRef:PathBuf 转换为 & ath
AsMut
- pub trait AsMut<T: ?Sized> {
- fn as_mut(&mut self) -> &mut T;
- }
复制代码 作用:将某个类型的可变引用转换为目标类型T的可变引用,常用于需要修改内部数据的场景- fn clear_buffer(buffer: &mut impl AsMut<[u8]>) {
- buffer.as_mut().fill(0); // 将缓冲区全部置零
- }
- fn main() {
- let mut vec = vec![1u8, 2, 3];
- clear_buffer(&mut vec); // 修改 Vec<u8>
- clear_buffer(&mut [4u8, 5]); // 修改数组切片
- }
复制代码 标准库实现举例
String: AsMut:String 的可变引用转为 &mut str
Vec: AsMut:Vec 的可变引用转为 &mut [T]
From
From是一个用于类型间安全、显示转换的核心trait,定义了一种值到值的转换方式。允许开发者将一种类型转换为另一种类型,同时确保转换的可靠性和所有权转移的清晰性。- pub trait From<T> {
- fn from(value: T) -> Self;
- }
复制代码 作用:将类型T的值转换为当前类型的值,表示一种无损且可靠的转换,通常是直接的构造或简单的数据重组。
关键特性:所有权转移,转换过程中会移动原始值,显示调用,需要显示调用from方法或使用Into trait的自动推导,鼓励高效实现,但运行必要的数据拷贝。- struct Meters(f64);
- struct Millimeters(f64);
- impl From<Meters> for Millimeters {
- fn from(m: Meters) -> Self {
- Millimeters(m.0 * 1000.0)
- }
- }
- let meters = Meters(2.5);
- let millimeters = Millimeters::from(meters);
复制代码 String::from(&str):将字符串切片 &str 转换为 String。
Vec::from(&[T]):将切片 &[T] 转换为 Vec。
Option::from(value):将值包装为 Some(value)。
基本数值类型之间的转换(如 i32 → i64)。
From和Into的关系
From和Into是互为逆操作的trait- pub trait Into<T> {
- fn into(self) -> T;
- }
- #[derive(Debug)]
- struct Meters(f64);
- struct Millimeters(f64);
- impl From<Meters> for Millimeters {
- fn from(m: Meters) -> Self {
- Millimeters(m.0 * 1000.0)
- }
- }
- // 自动获得 Into<Millimeters> 的实现
- let meters = Meters(2.5);
- let millimeters: Millimeters = meters.into();
- println!("{:?}", millimeters); // Millimeters(2500.0)
- // 接受任何可转换为 Millimeters 的类型
- fn print_length<T: Into<Millimeters>>(value: T) {
- let mm = value.into();
- println!("Length: {} mm", mm.0);
- }
- print_length(Meters(3.0)); // 直接传入 Meters 类型
- print_length(Millimeters(500.0)); // 也可传入 Millimeters 自身
复制代码 如果类型U实现了From, 则T自动获得Into的实现
错误处理中的应用
From trait 在错误处理中尤为重要,它允许将底层错误类型转换为自定义错误类型,简化 ? 运算符的使用- #[derive(Debug)]
- enum MyError {
- Io(std::io::Error),
- Parse(std::num::ParseIntError),
- }
- impl From<std::io::Error> for MyError {
- fn from(e: std::io::Error) -> Self {
- MyError::Io(e)
- }
- }
- impl From<std::num::ParseIntError> for MyError {
- fn from(e: std::num::ParseIntError) -> Self {
- MyError::Parse(e)
- }
- }
- fn read_file() -> Result<String, MyError> {
- let content = std::fs::read_to_string("file.txt")?; // 自动调用 MyError::from(io::Error)
- let _num: i32 = content.parse()?; // 自动调用 MyError::from(ParseIntError)
- Ok(content)
- }
复制代码 FromStr
FromStr是永远将字符串解析为特定类型的核心工具,表示一种可能是吧的解析操作- pub trait FromStr {
- type Err; // 关联类型,表示可能的错误类型
- fn from_str(s: &str) -> Result<Self, Self::Err>;
- }
复制代码 rust为所有实现了FromStr的类型提供了parse方法- use std::str::FromStr;
- let num = i32::from_str("42").unwrap(); // 42
- let flag = bool::from_str("true").unwrap(); // true
- let num: i32 = "42".parse().unwrap(); // 等价于 from_str
- let pi: f64 = "3.14".parse().unwrap();
复制代码 TryFrom
TryFrom是Rust标准库中定义的一个trait,用于表示可能失败的类型转换,是From的 安全提到方案。- pub trait TryFrom<T>: Sized {
- type Error;
- fn try_from(value: T) -> Result<Self, Self::Error>;
- }
复制代码 实现 TryFrom 会自动获得对应的 TryInto 实现
二者关系类似 From/Into
- use std::convert::TryFrom;
- fn main() {
- let big_num = 300i32;
-
- // 将 i32 转换为 u8(可能失败)
- match u8::try_from(big_num) {
- Ok(n) => println!("转换成功: {}", n),
- Err(_) => println!("数值溢出!300 > u8::MAX(255)"),
- }
- }
复制代码
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |