文字列とその文字列のスライスを含む構造体をRustで作成できますか?

Aug 22 2020

入力文字列を受け取り(そしてその所有権を取得し)、いくつかの計算を行ってから、文字列と文字列のいくつかの事前計算されたスライスを含む構造体を作成しようとしています。

何かのようなもの:

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
    }
}

ファイルcontentsが大きくなる可能性があるため、コピーしたくありません。関数costly_searchは計算に時間がかかる場合がありますが、常に入力のスライスを返します。そのスライスも大きいので、そのスライスを新しい文字列にコピーしたくありません。これも単純化されています。構造体に入力文字列の複数のスライスがあり、コンシューマーはすべてを渡し、必要に応じて事前に計算されたスライスを使用できます。

これをコンパイルしようとすると、次のようになります。

`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

私がやろうとしていることを達成する方法はありますか?

回答

2 JonasBerlin Aug 22 2020 at 00:22

costly_search()代わりに、その戻り開始インデックスと終了インデックスを文字列に入れて、それらをに渡すことができますMyString::new()か?その後、次のように毎回新しいスライスを作成できます

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