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

在rust中实现from_str时,如何在match语句中返回错误?,rust,Rust,我是新手。 我在这里尝试按照示例实现from_str trait 但我一直在得到这个指向“returnerr(Self::Err)”的错误 我知道为什么在我的枚举中没有定义Self::Err,但我不明白为什么rust在这种情况下会在意,因为我返回的是与结果类型内联的Err对象的Err 下面是我的FromStr,这是指向 impl FromStr解决玩家难题{ 类型Err=ParseError; fn来自_str(s:&str)->结果{ 让结果=匹配s{ “玩家”=>Ok(玩家难度::玩家),

我是新手。 我在这里尝试按照示例实现from_str trait

但我一直在得到这个指向“returnerr(Self::Err)”的错误

我知道为什么在我的枚举中没有定义Self::Err,但我不明白为什么rust在这种情况下会在意,因为我返回的是与结果类型内联的Err对象的Err

下面是我的FromStr,这是指向

impl FromStr解决玩家难题{
类型Err=ParseError;
fn来自_str(s:&str)->结果{
让结果=匹配s{
“玩家”=>Ok(玩家难度::玩家),
“经销商”=>正常(玩家难度::经销商),
“正常”=>Ok(玩家难度::正常),
“完美”=>Ok(玩家难度::完美),
“米奇”=>Ok(玩家难度::米奇),
“Elliot”=>Ok(玩家难度::Elliot),
“Cultist”=>Ok(玩家难度::Cultist),
_=>返回错误(Self::Err)
};
}
}
我做错了什么?
有更好的方法吗?

函数将返回它的最后一条语句。删除最后一个分号,也可以删除内部return语句,将返回
match
语句的结果

有更好的办法吗?看起来您正在将字符串解析为
enum
,create会这样做。您不必使用样板代码实现解析器,而只需派生它

#[derive(Debug, PartialEq, enum_utils::FromStr)]
enum PlayerDifficulty {
    Player,
    Dealer,
    Cultist,
    Normal,
}

fn main() {
    let _x:PlayerDifficulty= "Player".parse().unwrap();
}

在你的货物里

[dependencies]
enum-utils = "0.1.2"

您应该定义一个自定义错误

#[derive(Debug)]
struct PlayerError;

impl std::fmt::Display for PlayerError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "Could not parse player")
    }
}
impl std::error::Error for PlayerError{}

并将其与
一起使用以传播错误

fn main() -> (Result<(),Box<dyn std::error::Error>>) {
    let _x = PlayerDifficulty::from_str("Player")?;
    let _x = PlayerDifficulty::from_str("PlayerPlayer")?;
    Ok(())
}
fn main()->(结果){
let x=玩家难度::来自玩家?;
让x=playerDifficity::from_str(“PlayerPlayer”)?;
好(())
}

您的代码有三个问题。首先,如果要在
FromStr
实现中引用
Err
类型,则需要使用
::Err

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)
        };
    }
}
最后,即使转换成功,也需要通过删除
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),
        }
    }
}
结构未知困难错误;
针对球员难度的impl FromStr{
类型Err=未知困难错误;
fn来自_str(s:&str)->结果{
火柴{
“玩家”=>Ok(玩家难度::玩家),
/* ... */
_=>返回错误(未知困难错误),
}
}
}

函数将返回最后一条语句。删除最后一个分号,还可以删除内部return语句。如果您编写
return Err(::Err)
而不是
return Err(Self::Err)
,则错误将消失。但是,这可能会导致其他问题,具体取决于
parserror
的来源,但由于您没有提供一个示例,因此很难预测这些问题可能是什么(特别是
std::string::parserror
永远无法实例化,因此如果这是
parerror
您的意思,则代码无法工作)@jmb我加了一个伊萨克斯先生。不过我不明白这里发生了什么“::Err”来自其他语言“as”看起来像演员阵容?这是不是将我的玩家难度目标转化为一种特质?这在rust中是如何工作的?这里是
Self
播放难度
enum和“实现
FromStr
”的东西。当您编写
Self::Foo
时,编译器需要知道它是否必须在
playerDifficulity
枚举中或在
FromStr
特征中查找
Foo
(特别是因为两者中都可能有名为
Foo
)。默认情况下,它查看枚举本身,
语法告诉它查看
FromStr
实现。
fn main() -> (Result<(),Box<dyn std::error::Error>>) {
    let _x = PlayerDifficulty::from_str("Player")?;
    let _x = PlayerDifficulty::from_str("PlayerPlayer")?;
    Ok(())
}
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)
        };
    }
}
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),
        };
    }
}
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),
        }
    }
}