構造体内のライフタイム
借用されたフィールド
「構造体内のライフタイム」はCoddyKit上の無料Learn Rust Codingレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLearn Rust Coding学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Learn Rust Codingコースには全4レッスンが含まれています。
構造体は借用できる
ほとんどの構造体はデータを所有します。しかし構造体は、所有していないデータへの参照を保持することもできます。その場合、構造体にはライフタイムパラメーターが必要です。
これにより、構造体が借用したデータより長く存続しないことが保証されます。
構造体でライフタイムを宣言する
構造体名の後に山かっこでライフタイムを追加し、そのライフタイムを参照フィールドで使用します。これにより、構造体がその参照より長く存続できないことを示します。
struct Excerpt<'a> {
text: &'a str,
}
fn main() {
let novel = String::from("Call me Ishmael. Some years ago...");
let first = novel.split('.').next().unwrap();
let e = Excerpt { text: first };
println!("{}", e.text);
}追加される制約
この注釈により、Excerptのインスタンスは、借用している文字列が有効な間だけ有効になります。コンパイラーは、構造体が使用されるすべての場所でこれを強制します。
借用する構造体のメソッド
このような構造体のメソッドも、implヘッダーにライフタイムを持ちます。多くの場合、elision(次のレッスンで説明します)のおかげで、メソッド本体ではライフタイムを省略できます。
struct Excerpt<'a> { text: &'a str }
impl<'a> Excerpt<'a> {
fn announce(&self) -> &str {
println!("Attention!");
self.text
}
}
fn main() {
let s = String::from("hello world");
let e = Excerpt { text: &s };
println!("{}", e.announce());
}データを所有するだけではいけない理由
所有する(Stringを使う)方が簡単で、通常はこちらが推奨されます。借用すれば大きなデータのコピーを避けられるため、既存のバッファーを参照するパーサーやビューに役立ちます。
構造体でライフタイムを使うのは、借用することでメリットが得られる場合だけにしましょう。
パーサービューの例
ソース文字列内のスライスを保持する構造体は、典型的な用途です。コピーを作らずに元のバッファーを読み取れます。
struct Token<'a> {
word: &'a str,
}
fn main() {
let line = String::from("let x = 5");
let tokens: Vec<Token> = line.split_whitespace().map(|w| Token { word: w }).collect();
for t in &tokens {
println!("token: {}", t.word);
}
}複数の参照フィールド
構造体は複数の参照を保持できます。それらの有効性の関係に応じて、1つのライフタイムを共有することも、異なるライフタイムを使うこともできます。
struct Pair<'a> {
left: &'a str,
right: &'a str,
}
fn main() {
let a = String::from("foo");
let b = String::from("bar");
let p = Pair { left: &a, right: &b };
println!("{} {}", p.left, p.right);
}ダングリング構造体エラー
構造体がまだ存在する間に借用データが破棄されると、コンパイラーはそのコードを拒否します。ライフタイムパラメーターによって、このチェックが可能になります。
借用する構造体を返す
このような構造体を作成する関数では、構造体のライフタイムが入力に関連付けられます。構造体は、渡されたデータより長く存続できません。
struct Wrap<'a> { inner: &'a str }
fn wrap<'a>(s: &'a str) -> Wrap<'a> {
Wrap { inner: s }
}
fn main() {
let text = String::from("wrapped");
let w = wrap(&text);
println!("{}", w.inner);
}所有と借用のトレードオフ
簡単な指針:
- データを独立して保持する必要がありますか?所有します(
String、Vec)。 - 既存データを短期間参照するビューですか?ライフタイムを付けて借用します。
メンタルモデル
'aを持つ構造体は、他人のノートに貼り付けた付箋のようなものです。そのノートが存在する間だけ意味を持ちます。Rustは、なくなったノートの付箋を決して読まないようにしてくれます。
簡単な確認
構造体におけるライフタイムについての理解度を確認しましょう。
まとめ
構造体でのライフタイムについて学びました。
- 参照を保持する構造体にはライフタイムパラメーターが必要です
- ライフタイムによって、構造体の有効性が借用データに関連付けられます
- メソッドでは
implヘッダーにライフタイムを記述します - 借用によって意味のあるコピーを避けられる場合を除き、所有する方を優先します
よくある質問
「構造体内のライフタイム」レッスンは無料ですか?
はい。「構造体内のライフタイム」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Learn Rust Codingコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Learn Rust Codingコースには全4レッスンが含まれています。
「構造体内のライフタイム」で何を学びますか?
借用されたフィールド ブラウザで直接実行するハンズオンコードでLearn Rust Codingを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Learn Rust Codingを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのLearn Rust Codingは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「構造体内のライフタイム」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このLearn Rust Codingレッスンでコードを書いて実行できますか?
はい。すべてのLearn Rust Codingレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。