到達点は、所有せずに読む、独占して変更する、参照の有効期間を区別することです。前提は第04回です。
借りることで移動を避ける
&T は共有参照、&mut T は可変参照です。通常の借用規則では、同じ対象に同時に使う複数の共有参照、または一つの可変参照を持ちます。共有参照と可変参照を衝突させないことで、読み取り中の予期しない変更を防ぎます。
fn first_word(text: &str) -> &str {
text.split_whitespace().next().unwrap_or("")
}
fn longer<'a>(left: &'a str, right: &'a str) -> &'a str {
if left.len() >= right.len() { left } else { right }
}
fn add_suffix(text: &mut String) {
text.push_str(" practice");
}
fn main() {
let mut title = String::from("Rust lesson");
let word = first_word(&title);
println!("{word}");
add_suffix(&mut title);
println!("{title}");
println!("{}", longer("Java", "Python"));
}
src/main.rsの出力はRust、Rust lesson practice、Pythonです。wordを最後に使った後なので、titleを可変借用できます。参照の使用期間は、常に変数の字面上のスコープ全体と同じとは限りません。
ライフタイムは寿命を延ばす呪文ではない
longerの 'a は、戻り値が二つの入力参照に関係する期間だけ有効であることを表します。ローカル変数を長生きさせる命令ではありません。関数内で作って消えるStringへの参照を返すことはできず、その場合はStringを所有値として返します。
&str はUTF-8文字列の借用された部分です。&[T] は配列やVecの要素列を借りるスライスです。読み取りだけの関数が &Vec<T> より &[T] を受け取ると、配列などにも使いやすくなります。
練習と解答
練習:例のadd_suffixの後に、もう一度wordを表示すると何が起きますか。
解答:wordがtitleを借用したまま可変借用することになるため、コンパイルで拒否されます。後で必要なのが独立した単語ならto_ownedでStringにする、順序を変えて参照の使用を先に終えるなど、必要な所有関係を選びます。
公式資料
Rust全20回の目次 | 前の回 | 次の回