我尝试使用
根据Playground的显示,此代码按预期工作。但是,由于字符串解析可能失败,我想使用
From
特质来“重载”函数(使其能够接受结构体和字符串):pub struct Measurement {
pub value: i16,
pub unit: char,
}
impl From<&str> for Measurement {
fn from(s: &str) -> Measurement {
let value = s[0..s.len() - 1].parse::<i16>().unwrap();
let unit = s.chars().last().unwrap();
return Measurement { value, unit };
}
}
pub fn print_measurement<T: Into<Measurement>>(value: T) {
let m = value.into();
println!("Measurement is {}{}", m.value, m.unit);
}
fn main() {
print_measurement("40m");
print_measurement(Measurement{value: 23, unit: 'g'});
}
根据Playground的显示,此代码按预期工作。但是,由于字符串解析可能失败,我想使用
try_into()
而不是into()
。因此如下:use std::convert::TryFrom;
#[derive(Debug)]
pub struct Measurement {
pub value: i16,
pub unit: char,
}
impl TryFrom<&str> for Measurement {
type Error = String;
fn try_from(s: &str) -> Result<Measurement, String> {
let value = s[0..s.len() - 1].parse::<i16>();
let unit = s.chars().last();
match (value, unit) {
(Ok(v), Some(u)) => Ok(Measurement { value: v, unit: u }),
_ => Err("Invalid value or unit".to_string()),
}
}
}
pub fn try_print_measurement<T: TryInto<Measurement>>(value: T) {
let m = value.try_into();
match m {
Ok(m) => println!("Measurement is {}{}", m.value, m.unit),
Err(e) => println!("Error when parsing: {:?}", e),
}
}
fn main() {
try_print_measurement("4_0m"); // <-- this line should fail to parse
try_print_measurement(Measurement{value: 23, unit: 'g'});
}
问题:
- 不幸的是,上面的代码出现了错误
error[E0277]: '<T as TryInto<Measurement>>::Error' doesn't implement 'Debug'
。为什么错误类型不是按照指定的String
而是<T as TryInto<Measurement>>::Error
?这个错误类型是什么意思? - 我尝试使用
let m = Measurement::try_from(value)
代替let m = value.try_into()
。但是出现了error[E0277]: the trait bound 'Measurement: From<T>' is not satisfied
这似乎很奇怪,因为我调用的是try_from
而不是from
。为什么会这样呢? - 如何正确实现
TryFrom
特性,以便可以按照概述处理解析错误? - 为什么我们需要通过
use std::convert::TryFrom
将TryFrom
引入作用域,而From
特性不需要这样做呢?
where <T as TryInto<Measurement>>::Error: std::fmt::Debug
。但我也想了解为什么。为什么try_into()
的错误类型不只是一个String
?因为我们有type Error = String;
。 - Phil-ZXX