使用 FromStr 为自定义类型实现 parse
下面示例展示如何为一个结构体实现 FromStr,以便支持:
let v: Stringable = "hello".parse().unwrap();
示例代码
#[derive(Debug)]
struct Stringable {
content: String,
}
impl std::str::FromStr for Stringable {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
if s != "" {
Ok(Stringable {
content: s.to_string(),
})
} else {
Err(())
}
}
}
用法示例
fn main() {
let s: Stringable = "abc".parse().unwrap();
println!("{:?}", s);
}
输出:
Stringable { content: "abc" }
使用 From 和 Into 实现类型转换
From 和 Into 是一对相关的 trait,用于实现类型之间的转换。
From<T> - 从类型 T 转换
实现 From<T> 后,可以使用 From::from() 或 T::from() 进行转换:
#[derive(Debug)]
struct Number {
value: i32,
}
impl From<i32> for Number {
fn from(value: i32) -> Self {
Number { value }
}
}
// 使用方式
fn main() {
let num = Number::from(42);
// 或者
let num: Number = 42.into();
println!("{:?}", num);
}
Into<T> - 转换为类型 T
Into 是 From 的逆操作。当你实现了 From<T>,Into 会自动实现:
#[derive(Debug)]
struct Number {
value: i32,
}
impl From<i32> for Number {
fn from(value: i32) -> Self {
Number { value }
}
}
fn main() {
let num: Number = 42.into();
println!("{:?}", num);
}
使用 TryFrom 和 TryInto 实现可能失败的类型转换
当转换可能失败时,使用 TryFrom 和 TryInto,它们返回 Result 类型。
TryFrom<T> - 尝试从类型 T 转换
#[derive(Debug, PartialEq)]
struct PositiveNumber {
value: i32,
}
impl std::convert::TryFrom<i32> for PositiveNumber {
type Error = String;
fn try_from(value: i32) -> Result<Self, Self::Error> {
if value > 0 {
Ok(PositiveNumber { value })
} else {
Err(format!("{} is not positive", value))
}
}
}
// 使用方式
fn main() {
match PositiveNumber::try_from(42) {
Ok(num) => println!("{:?}", num),
Err(e) => println!("Error: {}", e),
}
// 或者使用 ?
let num: PositiveNumber = 42.try_into().unwrap();
}
TryInto<T> - 尝试转换为类型 T
#[derive(Debug, PartialEq)]
struct PositiveNumber {
value: i32,
}
impl std::convert::TryFrom<i32> for PositiveNumber {
type Error = String;
fn try_from(value: i32) -> Result<Self, Self::Error> {
if value > 0 {
Ok(PositiveNumber { value })
} else {
Err(format!("{} is not positive", value))
}
}
}
fn main() {
let num: Result<PositiveNumber, _> = (-5).try_into();
match num {
Ok(n) => println!("{:?}", n),
Err(e) => println!("Error: {}", e),
}
}
使用 AsRef 和 AsMut 实现引用转换
AsRef<T> - 获取不可变引用
struct MyString {
data: String,
}
impl AsRef<str> for MyString {
fn as_ref(&self) -> &str {
&self.data
}
}
fn print_str(s: &str) {
println!("{}", s);
}
fn main() {
let my_str = MyString {
data: "hello".to_string(),
};
print_str(my_str.as_ref());
// 或者直接使用,因为 AsRef 会自动调用
print_str(&my_str);
}
AsMut<T> - 获取可变引用
struct MyVec {
data: Vec<i32>,
}
impl AsMut<Vec<i32>> for MyVec {
fn as_mut(&mut self) -> &mut Vec<i32> {
&mut self.data
}
}
fn modify_vec(v: &mut Vec<i32>) {
v.push(42);
}
fn main() {
let mut my_vec = MyVec { data: vec![1, 2, 3] };
modify_vec(my_vec.as_mut());
println!("{:?}", my_vec.data);
}
使用 Borrow 实现借用
Borrow 类似于 AsRef,但语义上表示”借用”关系,通常用于哈希表和比较操作:
use std::borrow::Borrow;
#[derive(Debug)]
struct MyString {
data: String,
}
impl Borrow<str> for MyString {
fn borrow(&self) -> &str {
&self.data
}
}
fn main() {
let my_str = MyString {
data: "hello".to_string(),
};
let s: &str = my_str.borrow();
println!("{}", s);
}
使用 ToOwned 实现克隆
ToOwned 是 Clone 的泛型版本,用于从借用类型创建拥有类型:
use std::borrow::ToOwned;
#[derive(Debug, Clone)]
struct MyString {
data: String,
}
impl ToOwned for MyString {
type Owned = MyString;
fn to_owned(&self) -> Self::Owned {
MyString {
data: self.data.clone(),
}
}
}
fn main() {
let borrowed = MyString {
data: "hello".to_string(),
};
let owned: MyString = borrowed.to_owned();
println!("{:?}", owned);
}
使用 FromIterator 从迭代器创建集合
FromIterator 允许从迭代器创建集合类型:
use std::iter::FromIterator;
#[derive(Debug)]
struct MyVec {
items: Vec<i32>,
}
impl FromIterator<i32> for MyVec {
fn from_iter<T: IntoIterator<Item = i32>>(iter: T) -> Self {
let items: Vec<i32> = iter.into_iter().collect();
MyVec { items }
}
}
fn main() {
let my_vec: MyVec = (1..=5).collect();
println!("{:?}", my_vec);
// 或者显式调用
let my_vec = MyVec::from_iter(1..=5);
println!("{:?}", my_vec);
}
总结
| Trait | 用途 | 返回类型 | 示例 |
|---|---|---|---|
FromStr |
从字符串解析 | Result<Self, Self::Err> |
"123".parse::<i32>() |
From<T> |
从类型 T 转换 | Self |
Number::from(42) |
Into<T> |
转换为类型 T | T |
42.into() |
TryFrom<T> |
尝试从类型 T 转换 | Result<Self, Self::Error> |
PositiveNumber::try_from(42) |
TryInto<T> |
尝试转换为类型 T | Result<T, <T as TryFrom>::Error> |
42.try_into() |
AsRef<T> |
获取不可变引用 | &T |
my_str.as_ref() |
AsMut<T> |
获取可变引用 | &mut T |
my_vec.as_mut() |
Borrow<T> |
借用 | &T |
my_str.borrow() |
ToOwned |
创建拥有类型 | Self::Owned |
borrowed.to_owned() |
FromIterator<T> |
从迭代器创建集合 | Self |
(1..5).collect() |