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]