【问题标题】:Can I declare an enum value that takes a String or &str without needing additional functions?我可以声明一个采用 String 或 &str 而不需要其他函数的枚举值吗?
【发布时间】:2022-01-18 19:13:57
【问题描述】:

我有一个带有String 的枚举:

enum MyLovelyEnum {
    Thing(String),
}

对于测试,我希望能够传入 &'static str 以避免一遍又一遍地使用 MyLovelyEnum::Thing("abc".to_string)

我发现你可以用带有构造函数的结构很好地做到这一点:

// From: https://hermanradtke.com/2015/05/06/creating-a-rust-function-that-accepts-string-or-str.html
struct Person {
    name: String,
}

impl Person {
    fn new<S: Into<String>>(name: S) -> Person {
        Person { name: name.into() }
    }
}

fn main() {
    let person = Person::new("Herman");
    let person = Person::new("Herman".to_string());
}

我知道我可以使用生命周期或Cow,如What's the best practice for str/String values in Rust enums? 中所述,或者我可以创建自己的函数。

在博文中的枚举示例中是否有类似的内容?例如

// this is the kind of thing I am after but this specifically is not correct syntax
enum MyLovelyEnum {
  Thing<S: Into<String>>(S)
}

【问题讨论】:

  • 您为什么不想完全按照博客文章的功能为您的枚举创建一个构造函数?
  • 正如我所说的我知道我可以做到,我想知道是否有类似的东西:我有一个带字符串的枚举:``` enum MyLovelyEnum { Thing>(S) , } ``` 有可能吗?
  • 这不是“像博客文章”。博客文章创建了一个构造函数关联函数。你为什么不想为你的枚举创建一个?
  • 我为听起来充满敌意而道歉;那不是我的意图。我只是不明白这个问题,所以我问。你有一个声明“可以很好地做到这一点”的解决方案,所以我不明白你为什么不想使用它。您的帖子也没有解释创建构造函数有什么错误。您问“在博文中的枚举示例中是否有类似的内容?”。你似乎已经知道你可以为枚举创建一个构造函数,所以我看不出我们如何从帖子中的内容到其他任何地方,所以我提出问题。
  • 我特别想知道您是否可以声明一个 Enum 值,该值采用 String 或 &str 而无需其他功能。以我尝试过的博客为例:``` enum MyLovelyEnum { Thing>(S) } ``` 这是无效的。我不太了解 Rust,无法说出我对语法的尝试是否错误但有可能,或者根本不可能。我怀疑是后者

标签: string rust enums coercion


【解决方案1】:

您可以创建一个通用枚举:

enum MyLovelyEnum<S>
where
    S: Into<String>,
{
    Thing(S),
}

MyLovelyEnum::Thing("a");
MyLovelyEnum::Thing("b".to_string());

我可能不会在我的代码中这样做,而是选择创建一个构造函数,就像您链接的博客文章一样:

enum MyLovelyEnum {
    Thing(String),
}

impl MyLovelyEnum {
    fn thing(s: impl Into<String>) -> Self {
        MyLovelyEnum::Thing(s.into())
    }
}

MyLovelyEnum::thing("a");
MyLovelyEnum::thing("b".to_string());

【讨论】:

  • 我要补充一点,对于第一种方法,每个函数使用这个枚举都必须调用.into(),这意味着你将承担转换为String的开销每次你调用一个函数,这通常不是你想要的。
  • @ChayimFriedman 虽然您的评论精神属实,但我要指出您可以将MyLovelyEnum&lt;S&gt; 转换为MyLovelyEnum&lt;String&gt;,然后将其传递给您的其余部分程序。那么只有 API 的“外壳”需要处理灵活性,其余的可以假设为固定的String
  • 是的,我指的是 API,而不是内部细节。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多