如何创建包含字符串成员的Rust结构体?

119

我希望结构体拥有成员。我正在寻找结构体的正确声明和实例化示例,但我没有找到示例。


1
使用 String,请注意通过 .to_string()&str 创建 String 将涉及堆分配和复制整个字符串。 - sellibitze
1个回答

165
如果字符串必须由结构体拥有,那么您应该使用 String。或者,您可以使用具有静态生存期(即程序的生存期)的&str。例如:

如果字符串必须由结构体拥有,那么您应该使用 String。或者,您可以使用具有静态生存期(即程序的生存期)的&str。例如:

struct Foo {
    bar: String,
    baz: &'static str,
}

fn main() {
    let foo = Foo {
        bar: "bar".to_string(),
        baz: "baz",
    };
    println!("{}, {}", foo.bar, foo.baz);
}

如果字符串的生命周期未知,则可以使用生命周期参数为 Foo 进行参数化:

struct Foo<'a> {
    baz: &'a str,
}

另请参见:

如果不确定字符串是否拥有所有权(有助于避免分配内存),则可以使用 borrow::Cow

use std::borrow::Cow;

struct Foo<'a> {
    baz: Cow<'a, str>,
}

fn main() {
    let foo1 = Foo {
        baz: Cow::Borrowed("baz"),
    };
    let foo2 = Foo {
        baz: Cow::Owned("baz".to_string()),
    };
    println!("{}, {}", foo1.baz, foo2.baz);
}

注意,Cow 类型是在生命周期上进行参数化的。 生命周期指的是借用的字符串的生命周期(即当它是 Borrowed 时)。 如果你有一个 Cow,那么你可以使用 borrow 方法并获得一个 &'a str,然后就可以像使用普通字符串一样进行操作,而不必担心是否要分配新字符串。 通常情况下,由于解引用强制转换,不需要显式调用 borrow 方法。 也就是说,Cow 值会自动解引用为其借用形式,因此类型为 Cow<'a, str>val 变量可以使用 &*val 获得一个 &str


6
谢谢您提供完整的答案。我需要再考虑一下有关生命周期参数化的问题 :) - vladimir
1
如果我有一个包括Copy属性的结构体(例如#[derive(Clone, Copy)]),那么String就无法编译。最好的解决方案是什么? - tatmanblue
4
不使用字符串?这个回答可能显得简短,但是你提问的方式让我没有太多选择。我怀疑你遇到了 XY 问题。我建议你提出一个新问题,详细说明你试图解决的实际问题。 - BurntSushi5
如果我知道我永远不想改变字符串,那么使用String而不是Box<str>有什么理由吗? - The Zach Man
我不这么认为。如果您不需要变异但想要所有权,则 Box<str> 似乎是正确的选择。 - BurntSushi5
显示剩余2条评论

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