纪晴丽 发表于 2025-5-31 23:23:34

Rust类型转换

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 可以转换为切片 &
PathBuf: AsRef:PathBuf 转换为 &Path
AsMut

pub trait AsMut<T: ?Sized> {
    fn as_mut(&mut self) -> &mut T;
}作用:将某个类型的可变引用转换为目标类型T的可变引用,常用于需要修改内部数据的场景
fn clear_buffer(buffer: &mut impl AsMut<>) {
    buffer.as_mut().fill(0); // 将缓冲区全部置零
}

fn main() {
    let mut vec = vec!;
    clear_buffer(&mut vec);    // 修改 Vec<u8>
    clear_buffer(&mut ); // 修改数组切片
}标准库实现举例
String: AsMut:String 的可变引用转为 &mut str
Vec: AsMut:Vec 的可变引用转为 &mut
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(&):将切片 & 转换为 Vec。
Option::from(value):将值包装为 Some(value)。
基本数值类型之间的转换(如 i32 → i64)。
From和Into的关系

From和Into是互为逆操作的trait
pub trait Into<T> {
    fn into(self) -> T;
}

#
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 在错误处理中尤为重要,它允许将底层错误类型转换为自定义错误类型,简化 ? 运算符的使用
#
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)"),
    }
}
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: Rust类型转换