我尝试使用该特征“重载”函数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'});
}
Run Code Online (Sandbox Code Playgroud)
根据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'});
}
Run Code Online (Sandbox Code Playgroud)
问题:
error[E0277]: '<T as TryInto<Measurement>>::Error' doesn't implement 'Debug'。为什么错误类型不等于String指定的,而是等于<T as TryInto<Measurement>>::Error?这个错误类型是什么意思?let m = value.try_into()我尝试过let m = Measurement::try_from(value)。但这失败了error[E0277]: the trait bound 'Measurement: From<T>' is not satisfied,这看起来很奇怪,因为我称之为try_from(而不是from)。这是为什么?TryFrom特征,以便可以按照概述处理解析错误?TryFromvia 纳入范围use std::convert::TryFrom,而FromTrait 不需要这样做?TryInto<Measurement>都会使用Stringfor TryFrom::Error?遵循编译器提示。您可以有一个impl TryFrom<i32> for Measurement使用不同关联类型的实现或任何内容。
pub fn try_print_measurement<T>(value: T)
where
T: TryInto<Measurement>,
<T as TryInto<Measurement>>::Error: std::fmt::Debug,
{
let m = value.try_into();
match m {
Ok(m) => println!("Measurement is {}{}", m.value, m.unit),
Err(e) => println!("Error when parsing: {:?}", e),
}
}
Run Code Online (Sandbox Code Playgroud)
TryInto<Measurement>不是TryFrom<&str>。实施TryInto时已空白实施,而不是相反。TTryFrom| 归档时间: |
|
| 查看次数: |
6543 次 |
| 最近记录: |