假设您有一个想要解析的具体类型(您创建/拥有的),但该类型有一个通用字段,在这个例子中,我们会说可能的类型只有u8
,u16
& u32
,并且我们只能说其他任何东西都是不正确的或太大。
假设以下情况:
- 我已经简化了我实际使用的代码
- 我不能直接转换为相同的类型,它们必须根据大小为 u8、u16 或 u32(粗略地模拟我实际想要的
- 我这样展示是因为实际代码引入了太多内容,这是最小代码示例
- 我已经尝试过对每个类型执行等操作
impl FromStr for Test<u8> {}
,但随后编译器会抱怨(测试需要泛型),然后当我添加时会抱怨实现冲突,impl<T> FromStr for Test<T> {}
这是有道理的,因为 rust 还没有专业化 - 实际代码不使用
u8
,u16
或者u32
,我正在尝试使我的示例代码更广泛地适用
我有以下代码:
use std::str::FromStr;
#[derive(Debug)]
struct Test<T = u8> {
field: T
}
impl<T> FromStr for Test<T> {
type Err = std::num::ParseIntError;
fn from_str(buff: &str) -> Result<Test<T>, Self::Err> {
let attempt: Result<u8, Self::Err> = buff.parse();
if let Ok(field) = attempt { return Ok(Test::<u8> { field }) };
let attempt: Result<u16, Self::Err> = buff.parse();
if let Ok(field) = attempt { return Ok(Test::<u16> { field }) };
let attempt: Result<u32, Self::Err> = buff.parse();
match attempt {
Ok(field) => Ok(Test::<u32> { field }),
Err(err) => Err(err)
}
}
}
fn main() -> Result<(), std::num::ParseIntError> {
let u_8 = "128";
let u_16 = "475";
let u_32 = "70000";
let test_8: Test = u_8.parse()?;
let test_16: Test = u_16.parse()?;
let test_32: Test = u_32.parse()?;
println!("t8: {test_8:?}");
println!("t16: {test_16:?}");
println!("t32: {test_32:?}");
Ok(())
}
我收到大量错误,例如:
= note: expected struct `Test<T>`
found struct `Test<u16>`
这是有道理的。
我该如何让它工作?
奖励积分
为什么 Rust 要求我这样做Test::<u8>
,因为我已经在每一行上方指定了类型,return
为什么 Rust 不能直接推断出T
in Test<T>
?
是因为Result<Self, Self::Err>
和Self
吗Test<T>
?
假设我们有一个解析类型的函数。要么它是通用的,您需要在调用该函数时决定变体,要么它将具有单一返回类型。无论哪种方式,当您调用此函数时,它将具有单一明确的返回类型。
现在有两种方法可以让这个单一类型成为不同可能性的前端:它可以是一个枚举,列出预定数量的可能性,也可以是某种隐含特定特征的东西(如
Box<dyn Display>
),以提供可扩展数量的可能性。没有其他可能。