在 Rust 中实现 from_str 时,如何在 match 语句中返回错误?

DNS*_*zus 3 rust

我是生锈新手。我试图按照此处实现 from_str 特征的示例
https://doc.rust-lang.org/std/str/trait.FromStr.html

但我不断收到此错误,指向“return Err(Self::Err)”

variant or associated item not found in `black_jack_tools::PlayerDifficulty`
Run Code Online (Sandbox Code Playgroud)

我知道为什么 Self::Err 没有在我的枚举中定义,但我不明白为什么 rust 在这种情况下关心,因为我返回了 Err 对象的 Err,它与 Result<Self, Self::Err> 类型。

这是我的 FromStr,下面是带有 MRE 的 Rust 游乐场的链接

impl FromStr for PlayerDifficulty {
    type Err = ParseError;
    fn from_str(s:&str) -> Result<Self,Self::Err>{
        let result = match s {
            "Player" => Ok(PlayerDifficulty::Player),
            "Dealer" => Ok(PlayerDifficulty::Dealer),
            "Normal" => Ok(PlayerDifficulty::Normal),
            "Perfect"=> Ok(PlayerDifficulty::Perfect),
            "Micky" =>  Ok(PlayerDifficulty::Micky),
            "Elliot" => Ok(PlayerDifficulty::Elliot),
            "Cultist"=> Ok(PlayerDifficulty::Cultist),
            _ => return Err(Self::Err)
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?有一个更好的方法吗?

Jmb*_*Jmb 7

您的代码存在三个问题。第一个是如果您想在实现中<Self as FromStr>::Err引用类型,则需要使用:ErrFromStr

impl FromStr for PlayerDifficulty {
    type Err = ParseError;
    fn from_str(s:&str) -> Result<Self,Self::Err>{
        let result = match s {
            "Player" => Ok(PlayerDifficulty::Player),
            /* ... */
            _ => return Err(<Self as FromStr>::Err)
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

Self::ErrErr尝试在枚举中查找变体PlayerDifficulty,但没有这样的变体。

第二个问题是,它std::string::ParseError实际上是 的别名std::convert::Infallible,这是一个永远不会发生且无法实例化的错误。由于您的转换可能会失败,因此您需要使用可以实例化的错误或定义您自己的错误:

struct UnknownDifficultyError;
impl FromStr for PlayerDifficulty {
    type Err = UnknownDifficultyError;
    fn from_str(s:&str) -> Result<Self,Self::Err>{
        let result = match s {
            "Player" => Ok(PlayerDifficulty::Player),
            /* ... */
            _ => return Err(UnknownDifficultyError),
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

let result = 最后,即使转换成功,您也需要通过删除和 分号来返回结果:

struct UnknownDifficultyError;
impl FromStr for PlayerDifficulty {
    type Err = UnknownDifficultyError;
    fn from_str(s:&str) -> Result<Self,Self::Err>{
        match s {
            "Player" => Ok(PlayerDifficulty::Player),
            /* ... */
            _ => return Err(UnknownDifficultyError),
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

操场

  • 这里 `Self` 既是 `PlayerDifficulty` 枚举,也是“实现 `FromStr` 的东西”。当你编写 `Self::Foo` 时,编译器需要知道是否必须在 `PlayerDifficulty` 枚举中或在 `FromStr` 特征中查找 `Foo`(特别是因为两者中可能都有名为 `Foo` 的东西) 。默认情况下,它在枚举本身中查找,“&lt;Self as FromStr&gt;”语法告诉它在“FromStr”实现中查找。 (3认同)