将 mp3_metadata::Genre 转换为字符串

Cast a mp3_metadata::Genre to String

我想将 mp3_metadata::Genre(它是一个枚举)转换为一个字符串,我试过了:

impl fmt::Display for mp3_metadata::Genre {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", self)
        // or, alternatively:
        // fmt::Debug::fmt(self, f)
    }
}

但是它告诉我

Genre` is not defined in the current crate
impl doesn't use only types from inside the current crate

我不知道是否有一种简单的方法可以在没有 impl 的情况下将枚举转换为 String(我是 rust 的初学者,我对 impl 了解不多)。

如果您特别需要 Display 特性,则需要在上游进行更改。但是,看起来该类型实现了 Debug,这意味着您可以在 println!format! 中使用 {:?} 等(就像您在发布的示例中所做的那样)。

你可以通过创建自己的类型来解决这个问题,它是 Genre 的包装器,并为此实现 Display(这是评论中提到的 new type idiom):

struct MyGenre(mp3_metadata::Genre);

impl fmt::Display for MyGenre {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", self.0)
    }
}

孤儿规则禁止您编写 impl 特征和类型都定义在不同 crate 中的地方。

所以你有两个选择:

  • 创造你自己的特质
  • 创建你自己的类型

创造你自己的特质

use mp3_metadata::Genre

trait ParseEnum {
    fn stringify(&self) -> String;
}

impl ParseEnum for Genre {
    fn stringify(&self) -> String {
        use Genre::{Rock, Pop};
        match self {
            Rock => format!("Rock"),
            Pop => format!("Pop"),
            _ => format!("Other")
        }
    }
}

fn main() {
    let g = Genre::Rock;
    println!("{}", g.stringify());
}

使用新类型模式创建您自己的类型

查看 lkolbly 的回答