Rust FromStr,其中要解析的类型具有通用字段,并且在尝试解析之前你不会知道类型

问题描述 投票:0回答:1

假设您有一个想要解析的具体类型(您创建/拥有的),但该类型有一个通用字段,在本例中,我们会说可能的类型只有

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
中的
Test<T>

是因为

Result<Self, Self::Err>
Self
Test<T>
吗?

parsing rust
1个回答
0
投票

假设我们有一个函数可以解析您的类型。要么它是通用的,并且您需要在调用该函数时决定一个变体,要么它将具有单一返回类型。无论哪种方式,当您调用此函数时,它将有一个明确的返回类型。

现在有两种方法可以使这个单一类型成为不同可能性的前面:它可以是一个列出预先确定数量的可能性的枚举,或者它可以是隐含特定特征的东西(如

Box<dyn Display>
),对于可扩展的可能性。没有别的办法了。

© www.soinside.com 2019 - 2024. All rights reserved.