找回密码
 立即注册
首页 业界区 安全 Rust类型转换

Rust类型转换

纪晴丽 2025-5-31 23:23:34
AsRef 和 AsMut

用于类型间廉价引用转换的Trait,为不同类型的引用提供了一种统一的访问方式
AsRef
  1. pub trait AsRef<T: ?Sized> {
  2.     fn as_ref(&self) -> &T;
  3. }
复制代码
作用: 将某个类型的不可变引用转换为目标类型T的不可变引用
表示当前类型可以视为某种T类型的引用,转换过程无副作用,直接取内部引用,不拷贝数据
常用于函数参数中接受多种类型输入, 例如同时兼容string和&str
  1. // 接受所有能转换为 &str 的类型
  2. fn print_length(s: impl AsRef<str>) {
  3.     println!("Length = {}", s.as_ref().len());
  4. }
  5. fn main() {
  6.     print_length("hello");      // &str
  7.     print_length(String::from("world")); // String
  8. }
复制代码
标准库实现举例
String: AsRef:String 可以转换为 &str
Vec: AsRef:Vec 可以转换为切片 &[T]
PathBuf: AsRef:PathBuf 转换为 &ath
AsMut
  1. pub trait AsMut<T: ?Sized> {
  2.     fn as_mut(&mut self) -> &mut T;
  3. }
复制代码
作用:将某个类型的可变引用转换为目标类型T的可变引用,常用于需要修改内部数据的场景
  1. fn clear_buffer(buffer: &mut impl AsMut<[u8]>) {
  2.     buffer.as_mut().fill(0); // 将缓冲区全部置零
  3. }
  4. fn main() {
  5.     let mut vec = vec![1u8, 2, 3];
  6.     clear_buffer(&mut vec);    // 修改 Vec<u8>
  7.     clear_buffer(&mut [4u8, 5]); // 修改数组切片
  8. }
复制代码
标准库实现举例
String: AsMut:String 的可变引用转为 &mut str
Vec: AsMut:Vec 的可变引用转为 &mut [T]
From

From是一个用于类型间安全、显示转换的核心trait,定义了一种值到值的转换方式。允许开发者将一种类型转换为另一种类型,同时确保转换的可靠性和所有权转移的清晰性。
  1. pub trait From<T> {
  2.     fn from(value: T) -> Self;
  3. }
复制代码
作用:将类型T的值转换为当前类型的值,表示一种无损且可靠的转换,通常是直接的构造或简单的数据重组。
关键特性:所有权转移,转换过程中会移动原始值,显示调用,需要显示调用from方法或使用Into trait的自动推导,鼓励高效实现,但运行必要的数据拷贝。
  1. struct Meters(f64);
  2. struct Millimeters(f64);
  3. impl From<Meters> for Millimeters {
  4.     fn from(m: Meters) -> Self {
  5.         Millimeters(m.0 * 1000.0)
  6.     }
  7. }
  8. let meters = Meters(2.5);
  9. 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
  1. pub trait Into<T> {
  2.     fn into(self) -> T;
  3. }
  4. #[derive(Debug)]
  5. struct Meters(f64);
  6. struct Millimeters(f64);
  7. impl From<Meters> for Millimeters {
  8.     fn from(m: Meters) -> Self {
  9.         Millimeters(m.0 * 1000.0)
  10.     }
  11. }
  12. // 自动获得 Into<Millimeters> 的实现
  13. let meters = Meters(2.5);
  14. let millimeters: Millimeters = meters.into();
  15. println!("{:?}", millimeters); // Millimeters(2500.0)
  16. // 接受任何可转换为 Millimeters 的类型
  17. fn print_length<T: Into<Millimeters>>(value: T) {
  18.     let mm = value.into();
  19.     println!("Length: {} mm", mm.0);
  20. }
  21. print_length(Meters(3.0)); // 直接传入 Meters 类型
  22. print_length(Millimeters(500.0)); // 也可传入 Millimeters 自身
复制代码
如果类型U实现了From, 则T自动获得Into的实现
错误处理中的应用

From trait 在错误处理中尤为重要,它允许将底层错误类型转换为自定义错误类型,简化 ? 运算符的使用
  1. #[derive(Debug)]
  2. enum MyError {
  3.     Io(std::io::Error),
  4.     Parse(std::num::ParseIntError),
  5. }
  6. impl From<std::io::Error> for MyError {
  7.     fn from(e: std::io::Error) -> Self {
  8.         MyError::Io(e)
  9.     }
  10. }
  11. impl From<std::num::ParseIntError> for MyError {
  12.     fn from(e: std::num::ParseIntError) -> Self {
  13.         MyError::Parse(e)
  14.     }
  15. }
  16. fn read_file() -> Result<String, MyError> {
  17.     let content = std::fs::read_to_string("file.txt")?; // 自动调用 MyError::from(io::Error)
  18.     let _num: i32 = content.parse()?;                   // 自动调用 MyError::from(ParseIntError)
  19.     Ok(content)
  20. }
复制代码
FromStr

FromStr是永远将字符串解析为特定类型的核心工具,表示一种可能是吧的解析操作
  1. pub trait FromStr {
  2.     type Err; // 关联类型,表示可能的错误类型
  3.     fn from_str(s: &str) -> Result<Self, Self::Err>;
  4. }
复制代码
rust为所有实现了FromStr的类型提供了parse方法
  1. use std::str::FromStr;
  2. let num = i32::from_str("42").unwrap(); // 42
  3. let flag = bool::from_str("true").unwrap(); // true
  4. let num: i32 = "42".parse().unwrap(); // 等价于 from_str
  5. let pi: f64 = "3.14".parse().unwrap();
复制代码
TryFrom

TryFrom是Rust标准库中定义的一个trait,用于表示可能失败的类型转换,是From的 安全提到方案。
  1. pub trait TryFrom<T>: Sized {
  2.     type Error;
  3.     fn try_from(value: T) -> Result<Self, Self::Error>;
  4. }
复制代码
实现 TryFrom 会自动获得对应的 TryInto 实现
二者关系类似 From/Into

  1. use std::convert::TryFrom;
  2. fn main() {
  3.     let big_num = 300i32;
  4.    
  5.     // 将 i32 转换为 u8(可能失败)
  6.     match u8::try_from(big_num) {
  7.         Ok(n) => println!("转换成功: {}", n),
  8.         Err(_) => println!("数值溢出!300 > u8::MAX(255)"),
  9.     }
  10. }
复制代码

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册