在变量中存储&str或String

3
假设我定义了一个带有字符串字段的结构体。该字段应该具备以下特点:
  1. 能够持有字符串的所有权(例如,当我想用生成的format值填充它时),
  2. 同时也能够持有不可变引用(在字符串已经被其他地方拥有且不想浪费性能进行克隆的情况下)。
在Rust中,我应该如何表达这个意思("要么是&str,要么是String")?
2个回答

8
有一个内置类型可以实现这个功能,std::borrow::Cow(缩写为Clone On Write)。通过指定Cow<'a, str>,你可以存储&'a str以及StringCow解引用为str,因此你可以调用str的方法,并提供了to_mut()into_owned()方法,当你需要调用String的方法时使用。

这不是一种内置类型:它在标准库中定义。你可以轻松地编写具有相同性能特征的自己的Cow;这里没有"编译器魔法"。 - Mark Saving
这不是一个内置类型:它在标准库中定义。你可以很容易地编写具有相同性能特征的自己的Cow;这里没有“编译器魔法”。 - Mark Saving
@MarkSaving 在某种意义上,它是内置的:标准库随同语言一起提供。内置并不一定意味着编译器的魔法。但我认为没有理由争论术语。 - Chayim Friedman
@MarkSaving 在某种意义上,它是内置的:标准库随语言一同提供。内置并不一定意味着编译器的魔法。但我认为没有必要争论术语的问题。 - Chayim Friedman
@MarkSaving 在某种意义上,它是内置的:标准库是随语言一起提供的。内置并不一定意味着编译器的魔法。但我认为没有必要争论术语的问题。 - undefined

1
std::borrow::Cow类型对你的用例来说已经足够了,正如另一个答案中所建议的。如果你想要一些带有额外约束的自定义类型,你可以尝试按照下面的方式定义自己的枚举。
在Rust中,你可以使用枚举来表示既可以持有String类型也可以持有&str类型的字段。枚举允许你定义一个类型,该类型可以有多个变体,每个变体都有自己的数据。
enum MyString {
  Owned(String),
  Borrowed(&'static str),
}

struct MyStruct {
  field: MyString,
}

在上面的例子中,MyString枚举有两个变体:Owned,它持有一个String并表示拥有字符串的所有权,以及Borrowed,它持有一个&str并表示对字符串的不可变引用。
然后,您可以使用MyStruct结构体,并根据需要填充字段,可以是String或&str。

1
这在一般情况下是正确的,但在这种情况下定义一个枚举是不好的,因为标准库已经提供了一个。 - Chayim Friedman
1
这在一般情况下是正确的,但在这种情况下定义一个枚举是不好的,因为标准库已经提供了一个。 - Chayim Friedman
1
这在一般情况下是正确的,但在这种情况下定义一个枚举是不好的,因为标准库已经提供了一个。 - undefined
@ChayimFriedman 我完全同意你的观点。只有在希望获得定制化产品时,才适用于自己创建的方法。 - Sangam Belose
&amp;&#39;static str 无法持有对“在其他地方拥有的字符串”的引用。 - cafce25
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接