编写包含字符串并可在常量中使用的 Rust 结构类型

2023-12-31

我正在开始使用 Rust。我想要一个包含(除其他外)字符串的结构:

#[derive(Clone, Debug)]
struct Foo {
    string_field: &str,  // won't compile, but suppose String or Box<str> or &'a str or &'static str...
}

我希望能够声明constants or statics of it:

static FOO1: Foo = Foo {
    string_field: "",
};

And I also希望能够让它包含在运行时构造的字符串:

let foo2 = Foo {
  string_field: ("a".to_owned() + "b").as_str(),
};

我可以添加一个生命周期参数Foo这样我就可以声明字符串引用具有相同的生命周期。这很好,除了它似乎需要一个显式的生命周期参数包含的一切 a Foo,这意味着它使我的程序的其余部分变得复杂(甚至是不关心是否能够使用常量表达式的部分)。

我可以写

enum StringOfAdequateLifetime {
    Static(&'static str),
    Dynamic(Box<str>),  // or String, if you like
}
struct Foo {
    string_field: StringOfAdequateLifetime,
}

到目前为止,这似乎有效,但写出的文字却很混乱Foos.

似乎很明显,所期望的runtime行为是合理的:当你放下一个Foo,删除它包含的字符串 - 如果它是静态的,则永远不会删除,因此不需要额外的信息来处理这两种情况。有没有一种干净的方法来向 Rust 请求这个?

(看来我可以使用某种“智能指针”类型来保存字符串也可以写成静态情况下的常量表达式,但我还没有在标准库中看到过,当我尝试泛化时StringOfAdequateLifetime为了适用于任何类型,我在实施和使用各种标准特征时遇到了进一步的复杂情况,例如Deref,我怀疑这是由于之间的差异Sized和非Sized types.)


Rust 标准库有一个针对这种具体用例的内置类型,Cow https://doc.rust-lang.org/stable/std/borrow/enum.Cow.html。它是一个枚举,可以表示引用或拥有的值,并在必要时克隆该值以允许可变访问。在您的特定用例中,您可以像这样定义结构:

struct Foo {
    string_field: Cow<'static, str>
}

然后,您可以通过两种方式之一实例化它,具体取决于您是想要借用的常量字符串还是拥有的运行时构造的值:

const BORROWED: Foo = Foo { string_field: Cow::Borrowed("some constant") };
let owned = Foo { string_field: Cow::Owned(String::from("owned string")) };

为了简化此语法,您可以使用以下类型为该类型定义自己的构造函数constfn 允许在常量上下文中使用借用的构造函数:

impl Foo {
    pub const fn new_const(value: &'static str) -> Self {
        Self { string_field: Cow::borrowed(value) }
    }

    pub fn new_runtime(value: String) -> Self {
        Self { string_field: Cow::Owned(value) }
    }
}

这允许您使用更简单的语法来初始化值:

const BORROWED: Foo = Foo::new_const("some constant");
let owned = Foo::new_runtime(String::from("owned string"));
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

编写包含字符串并可在常量中使用的 Rust 结构类型 的相关文章

随机推荐