From 6527b361bd0b472e3be03a24fac8cd0e25cac74a Mon Sep 17 00:00:00 2001 From: woodyZootopia Date: Thu, 24 Sep 2020 09:44:58 +0900 Subject: [PATCH 1/3] =?UTF-8?q?=E7=BF=BB=E8=A8=B3=E3=82=92=E3=82=A2?= =?UTF-8?q?=E3=83=83=E3=83=97=E3=83=87=E3=83=BC=E3=83=88=E3=80=82=E3=81=9D?= =?UTF-8?q?=E3=81=AE=E7=B5=90=E6=9E=9C=E3=81=A8=E3=81=97=E3=81=A6=20Fixes:?= =?UTF-8?q?=20#37?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../listing-10-17/output.txt | 4 + .../listing-10-20/src/main.rs | 1 + .../listing-10-21/output.txt | 4 + .../listing-10-23/src/main.rs | 2 + .../listing-10-25/src/main.rs | 2 + .../output.txt | 3 + .../src/main.rs | 1 + .../src/main.rs | 1 + .../src/main.rs | 1 + src/ch10-03-lifetime-syntax.md | 350 +++++------------- 10 files changed, 113 insertions(+), 256 deletions(-) diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/output.txt b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/output.txt index 5f9b71b0b..e95702e78 100644 --- a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/output.txt +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/output.txt @@ -1,15 +1,19 @@ $ cargo run Compiling chapter10 v0.1.0 (file:///projects/chapter10) error[E0597]: `x` does not live long enough +(エラー[E0597]: `x`の生存期間が短すぎます) --> src/main.rs:7:17 | 7 | r = &x; | ^^ borrowed value does not live long enough + | (借用された値の生存期間が短すぎます) 8 | } | - `x` dropped here while still borrowed + | (`x`は借用されている間にここでドロップされました) 9 | 10 | println!("r: {}", r); | - borrow later used here + | (その後、借用はここで使われています) error: aborting due to previous error diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/src/main.rs index 0f076a71d..e1a830aad 100644 --- a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/src/main.rs +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/src/main.rs @@ -3,5 +3,6 @@ fn main() { let string2 = "xyz"; let result = longest(string1.as_str(), string2); + // 最長の文字列は、{}です println!("The longest string is {}", result); } diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/output.txt b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/output.txt index 21fb93614..baaf69902 100644 --- a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/output.txt +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/output.txt @@ -1,12 +1,16 @@ $ cargo run Compiling chapter10 v0.1.0 (file:///projects/chapter10) error[E0106]: missing lifetime specifier +(エラー[E0106]: ライフタイム指定子が不足しています) --> src/main.rs:9:33 | 9 | fn longest(x: &str, y: &str) -> &str { | ^ expected lifetime parameter + | (ライフタイム引数があるべきです) | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y` + (助言: この関数の戻り値型は借用された値を含んでいますが、 + シグニチャは、それが`x`と`y`どちらから借用されたものなのか宣言していません) error: aborting due to previous error diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/src/main.rs index 836ec7295..8a4e6fefa 100644 --- a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/src/main.rs +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/src/main.rs @@ -1,10 +1,12 @@ // ANCHOR: here fn main() { + // 長い文字列は長い let string1 = String::from("long string is long"); { let string2 = String::from("xyz"); let result = longest(string1.as_str(), string2.as_str()); + // 一番長い文字列は{} println!("The longest string is {}", result); } } diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-25/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-25/src/main.rs index 2937b194c..25598d3f6 100644 --- a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-25/src/main.rs +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-25/src/main.rs @@ -3,7 +3,9 @@ struct ImportantExcerpt<'a> { } fn main() { + // 僕をイシュマエルとお呼び。何年か前・・・ let novel = String::from("Call me Ishmael. Some years ago..."); + // "'.'が見つかりませんでした" let first_sentence = novel.split('.').next().expect("Could not find a '.'"); let i = ImportantExcerpt { part: first_sentence, diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/output.txt b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/output.txt index cadd5fa32..acdf96e4e 100644 --- a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/output.txt +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/output.txt @@ -1,6 +1,7 @@ $ cargo run Compiling chapter10 v0.1.0 (file:///projects/chapter10) error[E0515]: cannot return value referencing local variable `result` +(エラー[E0515]: ローカル変数`result`を参照している値は返せません) --> src/main.rs:11:5 | 11 | result.as_str() @@ -8,6 +9,8 @@ error[E0515]: cannot return value referencing local variable `result` | | | returns a value referencing data owned by the current function | `result` is borrowed here + | (現在の関数に所有されているデータを参照する値を返しています + | `result`はここで借用されています) error: aborting due to previous error diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/src/main.rs index aca4be0a7..ccd50f359 100644 --- a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/src/main.rs +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/src/main.rs @@ -8,6 +8,7 @@ fn main() { // ANCHOR: here fn longest<'a>(x: &str, y: &str) -> &'a str { + // 本当に長い文字列 let result = String::from("really long string"); result.as_str() } diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-10-lifetimes-on-methods/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-10-lifetimes-on-methods/src/main.rs index 32ad530b5..66036b26f 100644 --- a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-10-lifetimes-on-methods/src/main.rs +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-10-lifetimes-on-methods/src/main.rs @@ -13,6 +13,7 @@ impl<'a> ImportantExcerpt<'a> { // ANCHOR: 3rd impl<'a> ImportantExcerpt<'a> { fn announce_and_return_part(&self, announcement: &str) -> &str { + // "お知らせします: {}" println!("Attention please: {}", announcement); self.part } diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-11-generics-traits-and-lifetimes/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-11-generics-traits-and-lifetimes/src/main.rs index cfafa9a6d..0b6775208 100644 --- a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-11-generics-traits-and-lifetimes/src/main.rs +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-11-generics-traits-and-lifetimes/src/main.rs @@ -21,6 +21,7 @@ fn longest_with_an_announcement<'a, T>( where T: Display, { + // "アナウンス! {}" println!("Announcement! {}", ann); if x.len() > y.len() { x diff --git a/src/ch10-03-lifetime-syntax.md b/src/ch10-03-lifetime-syntax.md index 84066ec17..5bfdcce5b 100644 --- a/src/ch10-03-lifetime-syntax.md +++ b/src/ch10-03-lifetime-syntax.md @@ -5,17 +5,19 @@ ## ライフタイムで参照を検証する - -第4章の「参照と借用」節で議論しなかった詳細の一つに、Rustにおいて参照は全てライフタイムを保持するということがあります。 +One detail we didn’t discuss in the [“References and +Borrowing”][references-and-borrowing] section in Chapter 4 is +that every reference in Rust has a *lifetime*, which is the scope for which +that reference is valid. Most of the time, lifetimes are implicit and +inferred, just like most of the time, types are inferred. We must annotate +types when multiple types are possible. In a similar way, we must annotate +lifetimes when the lifetimes of references could be related in a few different +ways. Rust requires us to annotate the relationships using generic lifetime +parameters to ensure the actual references used at runtime will definitely be +valid. +--> + +第4章の[「参照と借用」][references-and-borrowing]節で議論しなかった詳細の一つに、Rustにおいて参照は全てライフタイムを保持するということがあります。 ライフタイムとは、その参照が有効になるスコープのことです。多くの場合、型が推論されるように、 大体の場合、ライフタイムも暗黙的に推論されます。複数の型の可能性があるときには、型を注釈しなければなりません。 同様に、参照のライフタイムがいくつか異なる方法で関係することがある場合には注釈しなければなりません。 @@ -30,14 +32,12 @@ The concept of lifetimes is somewhat different from tools in other programming languages, arguably making lifetimes Rust’s most distinctive feature. Although we won’t cover lifetimes in their entirety in this chapter, we’ll discuss common ways you might encounter lifetime syntax so you can become familiar with -the concepts. See the “Advanced Lifetimes” section in Chapter 19 for more -detailed information. +the concepts. --> ライフタイムの概念は、他のプログラミング言語の道具とはどこか異なり、間違いなく、 Rustで一番際立った機能になっています。この章では、ライフタイムの全てを講義しないものの、 ライフタイム記法と遭遇する可能性のある一般的な手段を議論するので、その概念に馴染めます。 -もっと詳しく知るには、第19章の「高度なライフタイム」節を参照されたし。 src/main.rs:7:5 - | -6 | r = &x; - | - borrow occurs here - | (借用はここで起きています) -7 | } - | ^ `x` dropped here while still borrowed - | (`x`は借用されている間にここでドロップされました) -... -10 | } - | - borrowed value needs to live until here - | (借用された値はここまで生きる必要があります) +```console +{{#include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/output.txt}} ``` Rustコンパイラには、スコープを比較して全ての借用が有効であるかを決定する*借用チェッカー*があります。 -リスト10-18は、リスト10-17と同じコードを示していますが、変数のライフタイムを表示する注釈が付いています: +リスト10-18は、リスト10-17と同じコードを示していますが、変数のライフタイムを表示する注釈が付いています。 -```rust,ignore -{ - let r; // ---------+-- 'a - // | - { // | - let x = 5; // -+-- 'b | - r = &x; // | | - } // -+ | - // | - println!("r: {}", r); // | -} // ---------+ +```rust,ignore,does_not_compile +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-18/src/main.rs:here}} ``` 関数に取ってほしい引数が文字列スライス、つまり参照であることに注意してください。 何故なら、`longest`関数に引数の所有権を奪ってほしくないからです。 -この関数に`String`のスライス(変数`string1`に格納されている型)と文字列リテラル(変数`string2`が含むもの)を受け取らせたいのです。 - - - リスト10-20で使用している引数が、我々が必要としているものである理由についてもっと詳しい議論は、 -第4章の「引数としての文字列スライス」節をご参照ください。 +第4章の[「引数としての文字列スライス」][string-slices-as-parameters]節をご参照ください。 src/main.rs:1:33 - | -1 | fn longest(x: &str, y: &str) -> &str { - | ^ expected lifetime parameter - | (ライフタイム引数が予想されます) - | - = help: this function's return type contains a borrowed value, but the -signature does not say whether it is borrowed from `x` or `y` - (助言: この関数の戻り値型は借用された値を含んでいますが、 -シグニチャは、それが`x`か`y`由来のものなのか宣言していません) +```console +{{#include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/output.txt}} ``` これで関数シグニチャは、何らかのライフタイム`'a`に対して、関数は2つの引数を取り、 どちらも少なくともライフタイム`'a`と同じだけ生きる文字列スライスであるとコンパイラに教えるようになりました。 また、この関数シグニチャは、関数から返る文字列スライスも少なくともライフタイム`'a`と同じだけ生きると、 -コンパイラに教えています。これらの制約は、コンパイラに強制してほしいものです。 +コンパイラに教えています。 +これは実際には、`longest`関数の返す参照のライフタイムは、渡される参照のライフタイムのうち短いほうだ、という意味です。 +これらの制約は、コンパイラに強制してほしいものです。 この関数シグニチャでライフタイム引数を指定する時、渡されたり、返したりした、いかなる値のライフタイムも変更していないことを思い出してください。 むしろ、借用チェッカーは、これらの制約を守らない値全てを拒否するべきと指定しています。 `longest`関数は、正確に`x`と`y`の生存期間を知る必要はなく、何かのスコープが`'a`に代替され、 @@ -563,24 +492,7 @@ a straightforward example. ファイル名: src/main.rs ```rust -# fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { -# if x.len() > y.len() { -# x -# } else { -# y -# } -# } -# -fn main() { - // 長い文字列は長い - let string1 = String::from("long string is long"); - - { - let string2 = String::from("xyz"); - let result = longest(string1.as_str(), string2.as_str()); - println!("The longest string is {}", result); - } -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/src/main.rs:here}} ``` src/main.rs:15:5 - | -14 | result = longest(string1.as_str(), string2.as_str()); - | ------- borrow occurs here -15 | } - | ^ `string2` dropped here while still borrowed -16 | println!("The longest string is {}", result); -17 | } - | - borrowed value needs to live until here +```console +{{#include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/output.txt}} ``` src/main.rs:3:5 - | -3 | result.as_str() - | ^^^^^^ does not live long enough -4 | } - | - borrowed value only lives until here - | -note: borrowed value must be valid for the lifetime 'a as defined on the -function body at 1:1... -(注釈: 借用された値は、関数本体1行目1文字目で定義されているようにライフタイム'aに対して有効でなければなりません) - --> src/main.rs:1:1 - | -1 | / fn longest<'a>(x: &str, y: &str) -> &'a str { -2 | | let result = String::from("really long string"); -3 | | result.as_str() -4 | | } - | |_^ +```console +{{#include ../listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/output.txt}} ``` @@ -1020,13 +871,15 @@ The compiler uses three rules to figure out what lifetimes references have when there aren’t explicit annotations. The first rule applies to input lifetimes, and the second and third rules apply to output lifetimes. If the compiler gets to the end of the three rules and there are still references for which it can’t -figure out lifetimes, the compiler will stop with an error. +figure out lifetimes, the compiler will stop with an error. These rules apply +to `fn` definitions as well as `impl` blocks. --> コンパイラは3つの規則を活用し、明示的な注釈がない時に、参照がどんなライフタイムになるかを計算します。 最初の規則は入力ライフタイムに適用され、2番目と3番目の規則は出力ライフタイムに適用されます。 コンパイラが3つの規則の最後まで到達し、それでもライフタイムを割り出せない参照があったら、 コンパイラはエラーで停止します。 +これらの規則は`fn`の定義にも`impl`ブロックと同様に適用されます。 -`impl`後のライフタイム引数宣言と型名の後に使用するのは必須ですが、最初の省略規則のため、 +`impl`後のライフタイム引数宣言と型名の後にそれを使用するのは必須ですが、最初の省略規則のため、 `self`への参照のライフタイムを注釈する必要はありません。 -議論する必要のある1種の特殊なライフタイムが、`'static`であり、これはプログラム全体の期間を示します。 +議論する必要のある1種の特殊なライフタイムが、`'static`であり、これはこの参照がプログラム全体において生きて*いられる*ことを表します。 文字列リテラルは全て`'static`ライフタイムになり、次のように注釈できます: ```rust -// 静的ライフタイムを持ってるよ +// 僕は静的ライフタイムを持ってるよ let s: &'static str = "I have a static lifetime."; ``` @@ -1313,19 +1148,7 @@ bounds, and lifetimes all in one function! ジェネリックな型引数、トレイト境界、ライフタイムを指定する記法を全て1関数でちょっと眺めましょう! ```rust -use std::fmt::Display; - -fn longest_with_an_announcement<'a, T>(x: &'a str, y: &'a str, ann: T) -> &'a str - where T: Display -{ - // アナウンス! - println!("Announcement! {}", ann); - if x.len() > y.len() { - x - } else { - y - } -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/no-listing-11-generics-traits-and-lifetimes/src/main.rs:here}} ``` 信じるかどうかは自由ですが、この章で議論した話題にはもっともっと学ぶべきことがあります: 第17章ではトレイトオブジェクトを議論します。これはトレイトを使用する別の手段です。 -第19章では、ライフタイム注釈が関わるもっと複雑な筋書きと何か高度な型システムの機能を講義します。 +非常に高度な状況でのみ必要となる、ライフタイム注釈に関する更に複雑な状況もあります;これらについては、[Rustリファレンス][reference]を読んでください。 ですが次は、コードがあるべき通りに動いていることを確かめられるように、Rustでテストを書く方法を学びます。 + + + +[references-and-borrowing]: +ch04-02-references-and-borrowing.html#参照と借用 +[string-slices-as-parameters]: +ch04-03-slices.html#引数としての文字列スライス + +[reference]: ../reference/index.html From d9f3daa53f867f13723faf0afcb91c3ddcf53c58 Mon Sep 17 00:00:00 2001 From: woodyZootopia Date: Thu, 24 Sep 2020 09:48:55 +0900 Subject: [PATCH 2/3] =?UTF-8?q?=E7=89=B9=E3=81=AB=E6=84=8F=E5=91=B3?= =?UTF-8?q?=E3=81=AE=E7=84=A1=E3=81=84=E6=96=87=E5=AD=97=E5=88=97=E3=81=AB?= =?UTF-8?q?=E3=82=B3=E3=83=A1=E3=83=B3=E3=83=88=E3=81=8C=E3=81=A4=E3=81=84?= =?UTF-8?q?=E3=81=A6=E3=81=84=E3=81=9F=E3=81=AE=E3=81=A7=E8=AA=AC=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../listing-10-23/src/main.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/src/main.rs index 8a4e6fefa..e54d5de45 100644 --- a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/src/main.rs +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/src/main.rs @@ -2,6 +2,7 @@ fn main() { // 長い文字列は長い let string1 = String::from("long string is long"); + // (訳注:この言葉自体に深い意味はない。下の"xyz"より長いということだけが重要) { let string2 = String::from("xyz"); From 93ccd91bbd4e7843b8616e09b35440b44fec6806 Mon Sep 17 00:00:00 2001 From: woodyZootopia Date: Thu, 24 Sep 2020 21:59:06 +0900 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BB=A5=E5=89=8D=E3=81=AE=E7=BF=BB?= =?UTF-8?q?=E8=A8=B3=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ch10-03-lifetime-syntax.md | 112 +++++++++++++++------------------ 1 file changed, 52 insertions(+), 60 deletions(-) diff --git a/src/ch10-03-lifetime-syntax.md b/src/ch10-03-lifetime-syntax.md index 5bfdcce5b..0bea59249 100644 --- a/src/ch10-03-lifetime-syntax.md +++ b/src/ch10-03-lifetime-syntax.md @@ -23,10 +23,6 @@ valid. 同様に、参照のライフタイムがいくつか異なる方法で関係することがある場合には注釈しなければなりません。 コンパイラは、ジェネリックライフタイム引数を使用して関係を注釈し、実行時に実際の参照が確かに有効であることを保証することを要求するのです。 - - -ライフタイムの概念は、他のプログラミング言語の道具とはどこか異なり、間違いなく、 -Rustで一番際立った機能になっています。この章では、ライフタイムの全てを講義しないものの、 -ライフタイム記法と遭遇する可能性のある一般的な手段を議論するので、その概念に馴染めます。 +ライフタイムの概念は、他のプログラミング言語の道具とはどこか異なり、間違いなくRustで一番際立った機能になっています。 +この章でライフタイムの全てを学ぶわけではありませんが、 +ライフタイム記法に遭遇しうる良くある状況について議論することで、その概念にみなさんが馴染めるようにします。 -今や、参照のライフタイムがどれだけあり、コンパイラがライフタイムを解析して参照が常に有効であることを保証する仕組みがわかったので、 -関数の文脈でジェネリックな引数と戻り値のライフタイムを探究しましょう。 +今や、参照のライフタイムがどれだけであるかと、コンパイラがライフタイムを解析して参照が常に有効であることを保証する仕組みがわかったので、 +関数における引数と戻り値のジェネリックなライフタイムを探究しましょう。 -リスト10-21に示したように`longest`関数を実装しようとしたら、コンパイルできないでしょう。 +リスト10-21に示すように`longest`関数を実装しようとしたら、コンパイルできないでしょう。 -この関数を定義する際、この関数に渡される具体的な値がわからないので、`if`ケースか、`else`ケースが実行されるか、わからないのです。 -また、渡される参照の具体的なライフタイムもわからないので、リスト10-18と10-19で、 -返す参照が常に有効であるかを決定したように、スコープを見ることもできないのです。 +この関数を定義する際、この関数に渡される具体的な値がわからないので、`if`ケースと`else`ケースのどちらが実行されるかわからないのです。 +また、リスト10-18と10-19で、返す参照が常に有効であるかを決定したときのようにスコープを見ることも、渡される参照の具体的なライフタイムがわからないのでできないのです。 借用チェッカーもこれを決定することはできません。`x`と`y`のライフタイムがどう戻り値のライフタイムと関係するかわからないからです。 -このエラーを修正するには、借用チェッカーが解析を実行できるように、参照間の関係を定義するジェネリックなライフタイム引数を追加します。 +このエラーを修正するために、借用チェッカーが解析を実行できるように、参照間の関係を定義するジェネリックなライフタイム引数を追加しましょう。 例を挙げましょう: ライフタイム引数なしの`i32`への参照、`'a`というライフタイム引数付きの`i32`への参照、 -そしてこれもライフタイム`'a`付きの`i32`への可変参照です。 +そして同じくライフタイム`'a`を持つ`i32`への可変参照です。 ```rust,ignore &i32 // a reference @@ -372,7 +367,7 @@ lifetime. お互いにどう関係するかをコンパイラに指示することを意図しているからです。例えば、 ライフタイム`'a`付きの`i32`への参照となる引数`first`のある関数があるとしましょう。 この関数にはさらに、`'a`のライフタイム付きの`i32`への別の参照となる`second`という別の引数もあります。 -ライフタイム注釈は、`first`と`second`の参照がどちらもジェネリックなライフタイムと同じだけ生きることを示唆します。 +ライフタイム注釈は、`first`と`second`の参照がどちらもそのジェネリックなライフタイムと同じだけ生きることを示唆します。 -これで関数シグニチャは、何らかのライフタイム`'a`に対して、関数は2つの引数を取り、 +これで関数シグニチャは、何らかのライフタイム`'a`があって、関数は2つの引数を取り、 どちらも少なくともライフタイム`'a`と同じだけ生きる文字列スライスであるとコンパイラに教えるようになりました。 また、この関数シグニチャは、関数から返る文字列スライスも少なくともライフタイム`'a`と同じだけ生きると、 コンパイラに教えています。 -これは実際には、`longest`関数の返す参照のライフタイムは、渡される参照のライフタイムのうち短いほうだ、という意味です。 +これは実際のところ、`longest`関数の返す参照のライフタイムは、渡される参照のライフタイムのうち短いほうだ、という意味です。 これらの制約は、コンパイラに強制してほしいものです。 この関数シグニチャでライフタイム引数を指定する時、渡されたり、返したりした、いかなる値のライフタイムも変更していないことを思い出してください。 むしろ、借用チェッカーは、これらの制約を守らない値全てを拒否するべきと指定しています。 -`longest`関数は、正確に`x`と`y`の生存期間を知る必要はなく、何かのスコープが`'a`に代替され、 -このシグニチャを満足することだけ知っている必要があることに注意してください。 +`longest`関数は、正確に`x`と`y`の生存期間を知る必要はなく、 +あるスコープがこのシグニチャを満たすような`'a`に代替できるということさえ分かっていればよいということに注意してください。 -具体的な参照を`longest`に渡すと、`'a`を代替する具体的なライフタイムは、`y`のスコープと被さる`x`のスコープの一部になります。 -言い換えると、ジェネリックなライフタイム`'a`は、`x`と`y`のライフタイムのうち、小さい方に等しい具体的なライフタイムになるのです。 +具体的な参照を`longest`に渡すと、`'a`を代替する具体的なライフタイムは、`y`のスコープと重複する`x`のスコープの一部になります。 +言い換えると、ジェネリックなライフタイム`'a`の具体的なライフタイムは、`x`と`y`のライフタイムのうち、小さい方に等しくなるのです。 返却される参照を同じライフタイム引数`'a`で注釈したので、返却される参照も`x`か`y`のライフタイムの小さい方と同じだけ有効になるでしょう。 -ライフタイム注釈が異なる具体的なライフタイムになる参照を渡すことで`longest`関数を制限する方法を見ましょう。 -リスト10-23は、率直な例です。 +異なる具体的なライフタイムを持つ参照を渡すことで、ライフタイム注釈が`longest`関数を制限する様子を見てみましょう。 +リスト10-23はそのシンプルな例です。 -試しに値や、`longest`関数に渡される参照のライフタイムや、返される参照の使用法が異なる実験をもっとしてみてください。 -自分の実験がコンパイル前に借用チェッカーを通るかどうか仮説を立ててください; そして、正しいか確かめてください! +試しに、値や、`longest`関数に渡される参照のライフタイムや、返される参照の使われかたが異なる実験をもっとしてみてください。 +コンパイル前に、その実験が借用チェッカーを通るかどうか仮説を立ててください; そして、正しいか確かめてください! 関数から参照を返す際、戻り値型のライフタイム引数は、引数のうちどれかのライフタイム引数と一致する必要があります。 -返される参照が引数のどれかを参照してい*なけれ*ば、この関数内で生成された値を参照しているに違いなく、 -これは、その値が関数の末端でスコープを抜けるので、ダングリング参照になるでしょう。 -コンパイルできないこの`longest`関数の未遂の実装を考えてください: +返される参照が引数のどれかを参照*していない*ならば、この関数内で生成された値を参照しているはずです。 +すると、その値は関数の末端でスコープを抜けるので、これはダングリング参照になるでしょう。 +以下に示す、コンパイルできない`longest`関数の未完成の実装を考えてください: 問題は、`result`が`longest`関数の末端でスコープを抜け、片付けられてしまうことです。 -また、関数から`result`を返そうともしています。ダングリング参照を変えるであろうライフタイム引数を指定する手段はなく、 +かつ、関数から`result`への参照を返そうともしています。ダングリング参照を変えてくれるようなライフタイム引数を指定する手段はなく、 コンパイラは、ダングリング参照を生成させてくれません。今回の場合、最善の修正案は、 -呼び出し元の関数が値の片付けに責任を持てるよう、参照ではなく所有されたデータ型を返すことでしょう。 +(呼び出し先ではなく)呼び出し元の関数に値の片付けをさせるために、参照ではなく所有されたデータ型を返すことでしょう。 -究極的にライフタイム記法は、関数のいろんな引数と戻り値のライフタイムを接続することに関するのです。 -一旦、繋がりができたら、メモリ安全な処理を許可するのに十分な情報がコンパイラにはあり、 -ダングリングポインタを生成するであろう処理を不認可し、さもなくばメモリ安全性を侵害するのです。 +つまるところライフタイム記法は、関数のいろんな引数と戻り値のライフタイムを「繋ぐ」ことに関係しているのです。 +それらが「繋がれ」てしまえば、メモリ安全な処理を許可したり、ダングリングポインタを生成するかメモリ安全性を脅かすような処理を不許可するのに十分な情報をコンパイラが持つことができます。 全参照にはライフタイムがあり、参照を使用する関数や構造体にはライフタイム引数を指定する必要があることを学びました。 -ですが、リスト4-9にとある関数があり、リスト10-26に再度示しましたが、 -これは、ライフタイム注釈なしでコンパイルできました。 +しかし、リスト4-9にあった関数(リスト10-26に再度示しました)はライフタイム注釈なしでコンパイルできました。 -リスト10-26: 引数と戻り値型が参照であるにも関わらず、ライフタイム注釈なしでコンパイルできた -リスト4-9で定義した関数 +リスト10-26: リスト4-9で定義した、引数と戻り値型が参照であるにも関わらず、ライフタイム注釈なしでコンパイルできた関数 -この関数がライフタイム注釈なしでコンパイルできた理由は、歴史的なものです: 昔のバージョンのRust(1.0以前)では、 +この関数がライフタイム注釈なしでコンパイルできる理由には、Rustの歴史が関わっています: 昔のバージョンのRust(1.0以前)では、 全参照に明示的なライフタイムが必要だったので、このコードはコンパイルできませんでした。 その頃、関数シグニチャはこのように記述されていたのです: @@ -819,9 +811,9 @@ the borrow checker could infer the lifetimes in these situations and wouldn’t need explicit annotations. --> -多くのRustコードを書いた後、Rustチームは、Rustプログラマが特定の場面では、 -何度も何度も同じライフタイム注釈を入力することを発見しました。これらの場面は予測可能で、 -いくつかの決定的なパターンに従っていました。開発者はこのパターンをコンパイラのコードに落とし込んだので、 +多くのRustコードを書いた後、Rustチームは、Rustプログラマが、 +特定の場面で何度も同じライフタイム注釈を入力していることを発見しました。これらの場面は予測可能で、 +いくつかの決まりきったパターンに従っていました。開発者はこのパターンをコンパイラのコードに落とし込んだので、 このような場面には借用チェッカーがライフタイムを推論できるようになり、明示的な注釈を必要としなくなったのです。 -他の決定的なパターンが出現し、コンパイラに追加されることもあり得るので、このRustの歴史は関係があります。 +ここで、このRustの歴史話が関係しているのは、他にも決まりきったパターンが出現し、コンパイラに追加されることもあり得るからです。 将来的に、さらに少数のライフタイム注釈しか必要にならない可能性もあります。 -コンパイラになってみましょう。これらの規則を適用して、リスト10-26の`first_word`関数のシグニチャの参照のライフタイムが何か計算します。 +コンパイラの立場になってみましょう。これらの規則を適用して、リスト10-26の`first_word`関数のシグニチャの参照のライフタイムが何か計算します。 シグニチャは、参照に紐づけられるライフタイムがない状態から始まります: ```rust,ignore @@ -997,7 +989,7 @@ couldn’t figure out all the lifetimes of the references in the signature. --> 2つ以上入力ライフタイムがあるので、2番目の規則は適用されないとわかります。また3番目の規則も適用されません。 -`longest`はメソッドではなく関数なので、どの引数も`self`ではないのです。3つの規則全部を適用した後、 +`longest`はメソッドではなく関数なので、どの引数も`self`ではないのです。3つの規則全部を適用した後でも、 まだ戻り値型のライフタイムが判明していません。このために、リスト10-21でこのコードをコンパイルしようとしてエラーになったのです: コンパイラは、ライフタイム省略規則全てを適用したけれども、シグニチャの参照全部のライフタイムを計算できなかったのです。 @@ -1007,8 +999,8 @@ lifetimes in that context next to see why the third rule means we don’t have t annotate lifetimes in method signatures very often. --> -3番目の規則は本当にメソッドシグニチャでしか適用されないので、次にその文脈でライフタイムを観察し、 -3番目の規則が、メソッドシグニチャであまり頻繁にライフタイムを注釈しなくても済むことを意味する理由を確認します。 +実際のところ、3番目の規則はメソッドのシグニチャにしか適用されません。ですので、次はその文脈においてライフタイムを観察し、 +3番目の規則のおかげで、メソッドシグニチャであまり頻繁にライフタイムを注釈しなくても済む理由を確認します。 -`impl`ブロック内のメソッドシグニチャでは、参照は構造体のフィールドの参照のライフタイムに紐づくか、 +`impl`ブロック内のメソッドシグニチャでは、参照は構造体のフィールドの参照のライフタイムに紐づいている可能性と、 独立している可能性があります。加えて、ライフタイム省略規則により、メソッドシグニチャでライフタイム注釈が必要なくなることがよくあります。 -リスト10-25で定義した`ImportantExcerpt`という構造体を使用して、何か例を見ましょう。 +リスト10-25で定義した`ImportantExcerpt`という構造体を使用した例をいくつか見てみましょう。 -エラーメッセージで`'static`ライフタイムを使用する提言を目撃する可能性があります。 +エラーメッセージで、`'static`ライフタイムを使用するよう勧める提言を見かける可能性があります。 ですが、参照に対してライフタイムとして`'static`を指定する前に、今ある参照が本当にプログラムの全期間生きるかどうか考えてください。 -可能であっても、参照がそれだけの期間生きてほしいかどうか考慮する可能性があります。 +それが可能であったとしても、参照がそれだけの期間生きてほしいのかどうか考慮するのも良いでしょう。 ほとんどの場合、問題は、ダングリング参照を生成しようとしているか、利用可能なライフタイムの不一致が原因です。 そのような場合、解決策はその問題を修正することであり、`'static`ライフタイムを指定することではありません。 @@ -1145,7 +1137,7 @@ Let’s briefly look at the syntax of specifying generic type parameters, trait bounds, and lifetimes all in one function! --> -ジェネリックな型引数、トレイト境界、ライフタイムを指定する記法を全て1関数でちょっと眺めましょう! +ジェネリックな型引数、トレイト境界、ライフタイム指定の構文のすべてを1つの関数で簡単に見てみましょう! ```rust {{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/no-listing-11-generics-traits-and-lifetimes/src/main.rs:here}} @@ -1186,8 +1178,8 @@ that this flexible code won’t have any dangling references. And all of this analysis happens at compile time, which doesn’t affect runtime performance! --> -いろんなことをこの章では講義しましたね!今やジェネリックな型引数、トレイトとトレイト境界、そしてジェネリックなライフタイム引数を知ったので、 -多くの異なる場面で動くコードを繰り返しなく書く準備ができました。ジェネリックな型引数により、 +たくさんのことをこの章では講義しましたね!今やジェネリックな型引数、トレイトとトレイト境界、そしてジェネリックなライフタイム引数を知ったので、 +多くの異なる場面で動くコードを繰り返すことなく書く準備ができました。ジェネリックな型引数により、 コードを異なる型に適用させてくれます。トレイトとトレイト境界は、型がジェネリックであっても、 コードが必要とする振る舞いを持つことを保証します。ライフタイム注釈を活用して、 この柔軟なコードにダングリング参照が存在しないことを保証する方法を学びました。 @@ -1202,7 +1194,7 @@ the [Rust Reference][reference]. But next, you’ll learn how to write tests in Rust so you can make sure your code is working the way it should. --> -信じるかどうかは自由ですが、この章で議論した話題にはもっともっと学ぶべきことがあります: +信じられないかもしれませんが、この章で議論した話題にはもっともっと学ぶべきことがあります: 第17章ではトレイトオブジェクトを議論します。これはトレイトを使用する別の手段です。 非常に高度な状況でのみ必要となる、ライフタイム注釈に関する更に複雑な状況もあります;これらについては、[Rustリファレンス][reference]を読んでください。 ですが次は、コードがあるべき通りに動いていることを確かめられるように、Rustでテストを書く方法を学びます。