119

I want the members to be owned by the struct. I'm looking for the correct declaration of a struct and instantiation examples. I wasn't able to find an example.

nbro
  • 15,395
  • 32
  • 113
  • 196
vladimir
  • 2,635
  • 3
  • 23
  • 26
  • 1
    Use `String` and be aware that creating a `String` from `&str` via `.to_string()` involves a heap allocation + copying the whole string. – sellibitze Sep 11 '14 at 12:13

1 Answers1

166

If the string has to be owned by the struct, then you should use String. Alternatively, you could use an &str with a static lifetime (i.e., the lifetime of the program). For example:

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

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

If the lifetime of the string is unknown, then you can parameterize Foo with a lifetime:

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

See also:

If you're not sure whether the string will be owned or not (useful for avoiding allocations), then you can use 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);
}

Note that the Cow type is parameterized over a lifetime. The lifetime refers to the lifetime of the borrowed string (i.e., when it is a Borrowed). If you have a Cow, then you can use borrow and get a &'a str, with which you can do normal string operations without worrying about whether to allocate a new string or not. Typically, explicit calling of borrow isn't required because of deref coercions. Namely, Cow values will dereference to their borrowed form automatically, so &*val where val has type Cow<'a, str> will produce a &str.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
BurntSushi5
  • 13,917
  • 7
  • 52
  • 45
  • 6
    Uhhh, thank you for the full answer. I need to think about the lifetime parametrization another day :) – vladimir Sep 10 '14 at 02:55
  • 1
    if I have a structure that includes the Copy attribute (eg #[derive(Clone, Copy)], then String doesn't compile. What is the best solution? – tatmanblue Apr 13 '18 at 20:38
  • 4
    Don't use String? That might seem like a curt answer, but the way you asked your question doesn't leave me much choice. I suspect you are hitting am instance of the XY problem. I'd recommend asking a new question detailing the actual problem you're trying to solve. – BurntSushi5 Apr 14 '18 at 03:35
  • The documentation states that `String` is mutable. If I have a struct with, say, a `name` field that should be immutable, should I still use `String` instead of `str`? – Ondra K. Nov 12 '20 at 10:30
  • I don't see how that's relevant to this question. I'd suggest you ask a new question. – BurntSushi5 Nov 12 '20 at 14:13
  • If I know I'm never going to want to mutate the string, is there a reason to use `String` over `Box`? – The Zach Man Jun 07 '22 at 18:53
  • I don't believe so. If you don't need mutation but want ownership, `Box` seems like the way to go. – BurntSushi5 Jun 07 '22 at 22:21