Tom Kludy
Tom Kludy

Reputation: 439

Can I create a struct in Rust containing a String and a slice of that String?

I am trying to create a struct that takes an input string (and takes ownership of it), does some calculations, then returns a struct that contains the string and some precomputed slices of the string.

Something like:

pub async fn read_file<'a>(path: &Path) -> Result<MyString<'a>> {
    let contents = tokio::fs::read_to_string(path).await?;
    let slice = costly_search(&contents);
    Ok(MyString::new(contents, slice))
}

pub struct MyString<'a>
{
    slice: &'a str,
    string: String,
}

impl<'a> MyString<'a> {
    pub fn new(string: String, slice: &'a str) -> MyString<'a> {
        MyString { string, slice }
    }
    pub fn get_slice(&self) -> &str {
        self.slice
    }
}

The file contents can be large so I don't want to copy it. The function costly_search can take some time to compute, but always returns a slice of its input; that slice is also large so I don't want to copy that slice into a new String. This is also simplified; I will have multiple slices of the input string in the struct and consumers can pass the whole thing around and use the precomputed slices as they need.

When I try to compile this I get:

`contents` does not live long enough

borrowed value does not live long enough
utils.rs(43, 31): borrowed value does not live long enough
utils.rs(45, 1): `contents` dropped here while still borrowed

Is there a way to accomplish what I'm trying to do?

Upvotes: 5

Views: 787

Answers (1)

Jonas Berlin
Jonas Berlin

Reputation: 3482

Can you make that costly_search() return start & end indexes into the string instead and pass those on to MyString::new()? Then you can create a new slice every time like

fn get_slice(&self) -> &str {
  &self.contents[self.start..self.end]
}

Upvotes: 2

Related Questions