From 4150bfa639cc9322c6575b11dc20b143f4d578b5 Mon Sep 17 00:00:00 2001 From: "Tatsuya Kawano (Circle CI)" Date: Sat, 25 Jun 2016 11:54:36 +0800 Subject: [PATCH] Update Structs to 1.9 --- 1.9/ja/book/structs.md | 234 ++++++++++++++-------- diff-1.6.0..1.9.0/src/doc/book/structs.md | 153 -------------- 2 files changed, 152 insertions(+), 235 deletions(-) delete mode 100644 diff-1.6.0..1.9.0/src/doc/book/structs.md diff --git a/1.9/ja/book/structs.md b/1.9/ja/book/structs.md index c1744517..270a3580 100644 --- a/1.9/ja/book/structs.md +++ b/1.9/ja/book/structs.md @@ -1,18 +1,20 @@ % 構造体 - -`struct` はより複雑なデータ型を作る方法の1つです。例えば、もし私たちが2次元空間の座標に関する計算を行っているとして、 `x` と `y` 、両方の値が必要になるでしょう。 + + + +`struct` はより複雑なデータ型を作る方法の1つです。 +例えば、もし私たちが2次元空間の座標に関する計算を行っているとして、 `x` と `y` 、両方の値が必要になるでしょう。 ```rust let origin_x = 0; let origin_y = 0; ``` - -`struct` でこれら2つを1つのデータ型にまとめることができます。 + + +`struct` でこれら2つを、`x` と `y` というフィールドラベルを持つ、1つのデータ型にまとめることができます。 ```rust struct Point { @@ -27,23 +29,32 @@ fn main() { } ``` - -ここで多くの情報が出てきましたから、順番に見ていきましょう。まず、 `struct` キーワードを使って構造体とその名前を宣言しています。慣習により、構造体は初めが大文字のキャメルケースで記述しています。 `PointInSpace` であり、 `Point_In_Space` ではありません。 - - -いつものように、 `let` で `struct` のインスタンスを作ることができますが、ここでは `key: value` スタイルの構文でそれぞれのフィールドに値をセットしています。順序は元の宣言と同じである必要はありません。 - - +> 訳注: +> +> The origin is at ({}, {}): 原点は ({}, {}) にあります。 + + + + +ここで多くの情報が出てきましたから、順番に見ていきましょう。 +まず `struct` キーワードを使って構造体とその名前を宣言しています。 +慣習により、構造体は頭文字が大文字のキャメルケースで記述しています。 +`PointInSpace` であり、 `Point_In_Space` ではありません。 + + + + +いつものように `let` で `struct` のインスタンスを作れますが、ここでは `key: value` スタイルの構文でそれぞれのフィールドに値をセットしています。 +順序は元の宣言と同じである必要はありません。 + + + 最後に、作成された構造体のフィールドは名前を持つため、 `origin.x` というようにドット表記でアクセスできます。 - -Rustの他の束縛のように、 `struct` が持つ値はイミュータブルがデフォルトです。 `mut` を使うと値をミュータブルにできます。 + + +Rustの他の束縛のように、 `struct` が持つ値はデフォルトでイミュータブルです。 +`mut` を使うと値をミュータブルにできます。 ```rust struct Point { @@ -61,12 +72,11 @@ fn main() { ``` -これは `The point is at (5, 0)` と出力されます。 - - -Rustは言語レベルでフィールドのミュータビリティに対応していないため、以下の様に書くことはできません。 +これは `The point is at (5, 0)` と表示します。 + + +Rustは言語レベルではフィールドのミュータビリティに対応していないため、以下のようには書けません。 ```rust,ignore struct Point { @@ -75,11 +85,14 @@ struct Point { } ``` - -ミュータビリティは束縛に付与できる属性であり、構造体自体に付与できる属性ではありません。もしあなたがフィールドレベルのミュータビリティを使うのであれば、初めこそ奇妙に見えるものの、非常に簡単に実現できる方法があります。以下の方法で少しの間だけミュータブルな構造体を作ることができます。 + + + + +ミュータビリティは束縛が持つ属性であり、構造体自体の属性ではないのです。 +もしあなたがフィールドレベルのミュータビリティに慣れているなら、初めは奇妙に映るかもしれません。 +しかし、このことが物事をとてもシンプルにしてくれます。 +またこれは、構造体を一時的にミュータブルにすることも可能にします。 ```rust,ignore struct Point { @@ -92,20 +105,51 @@ fn main() { point.x = 5; -# // let point = point; // this new binding can’t change now - let point = point; // この新しい束縛でここから変更できなくなります +# // let point = point; // now immutable + let point = point; // ここからは不変 # // point.y = 6; // this causes an error point.y = 6; // これはエラーになります } ``` + + +構造体に `&mut` ポインタを含めることはできますので、ある種の変更を行えます。 + +```rust +struct Point { + x: i32, + y: i32, +} + +struct PointRef<'a> { + x: &'a mut i32, + y: &'a mut i32, +} + +fn main() { + let mut point = Point { x: 0, y: 0 }; + + { + let r = PointRef { x: &mut point.x, y: &mut point.y }; + + *r.x = 5; + *r.y = 6; + } + + assert_eq!(5, point.x); + assert_eq!(6, point.y); +} +``` + # アップデート構文 - -`struct` の初期化時には、値の一部を他の構造体からコピーしたいことを示す `..` を含めることができます。例えば、 + + +`struct` の値を作る時に `..` を含めると、他の `struct` から一部の値をコピーしたいことを示せます。 +たとえば、 ```rust struct Point3d { @@ -118,10 +162,12 @@ let mut point = Point3d { x: 0, y: 0, z: 0 }; point = Point3d { y: 1, .. point }; ``` - -ここでは`point`に新しい`y`を与えていますが、`x`と`z`は古い値を維持します。どれかの`struct`と同じ値を作る他にも、この構文を新たな値の作成に使用でき、明示することなく値のコピーが行えます。 + + + +ここでは `point` に新しい `y` を与えていますが、`x` と `z` は古い値を維持します。 +これは同一の `struct` でなくても構いません。 +この構文を新しい `struct` の作成に使用でき、値を指定しなかったフィールドについてはコピーされます。 ```rust # struct Point3d { @@ -133,34 +179,43 @@ let origin = Point3d { x: 0, y: 0, z: 0 }; let point = Point3d { z: 1, x: 2, .. origin }; ``` +> 訳注: 原文の「同一の `struct` でなくても構いません」というのは、誤解を招くかもしれません。 +> まず、2種類の「別の型の」構造体の間では、この構文は使えません。 +> また、ある1種類の構造体のインスタンスについて考える場合でも、この構文によって、既存のインスタンスの値が「その場で更新」されるわけではないことに注意してください。 +> 実際には、既存のインスタンスのフィールド値を元に、新しいインスタンスが作られます。 +> +> つまり、「同一の `struct` でなくても構わない」というよりも、「ある `struct` 型の既存のインスタンスを元に、同じ型の新しいインスタンスを作る」ことしかできないのです。 + # タプル構造体 - -Rustには「タプル構造体」と呼ばれる、[タプル][tuple]と `struct` のハイブリットのようなデータ型があります。タプル構造体自体には名前がありますが、そのフィールドには名前がありません。 + + + + -```rust -struct Color(i32, i32, i32); -struct Point(i32, i32, i32); -``` +Rustには「タプル構造体」と呼ばれる、[タプル][tuple]と `struct` のハイブリットのようなデータ型があります。 +タプル構造体自体には名前がありますが、そのフィールドには名前がありません。 +これらは `struct` キーワードによって宣言され、名前と単一のタプルが続きます。 [tuple]: primitive-types.html#tuples - -これら2つは同じ値を持つ同士であったとしても等しくありません。 - ```rust -# struct Color(i32, i32, i32); -# struct Point(i32, i32, i32); +struct Color(i32, i32, i32); +struct Point(i32, i32, i32); let black = Color(0, 0, 0); let origin = Point(0, 0, 0); ``` - -ほとんどの場合タプル構造体よりも `struct` を使ったほうが良いです。 `Color` や `Point` はこのようにも書けます。 + + +ここで `black` と `origin` は同じ値を格納していますが、2者は等しくありません。 +(訳注: 2者は別の型として扱われます) + + + +ほとんどの場合タプル構造体よりも `struct` を使ったほうがいいでしょう。 +`Color` や `Point` はこのようにも書けます。 ```rust struct Color { @@ -176,17 +231,22 @@ struct Point { } ``` - -今、私たちはフィールドの位置ではなく実際のフィールドの名前を持っています。良い名前は重要で、 `struct` を使うということは、実際に名前を持っているということです。 + + + +良い名前は重要です。 +タプル構造体に格納された値はドット表記で参照できますが、 `struct` なら、フィールドの位置ではなく、実際のフィールドの名前で参照できます。 > 訳注: 原文を元に噛み砕くと、「タプルはフィールドの並びによって区別され、構造体はフィールドの名前によって区別されます。これはタプルと構造体の最たる違いであり、構造体を持つことは名前を付けられたデータの集まりを持つことに等しいため、構造体における名前付けは重要です。」といった所でしょうか。 - -タプル構造体が非常に便利な場合も _あります_ が、1要素で使う場合だけです。タプル構造体の中に入っている値と、それ自体のセマンティックな表現を明確に区別できるような新しい型を作成できることから、私たちはこれを「newtype」パターンと呼んでいます。 + + + + +タプル構造体が非常に便利な場合も _あります_ 。 +それは要素を1つだけ持つ時です。 +私たちはこれを「newtype」パターンと呼んでいます。 +なぜなら、それ自体のセマンティックな意味を表現でき、格納している値とは別の型として扱われる、新しい型が作れるからです。 ```rust struct Inches(i32); @@ -197,16 +257,23 @@ let Inches(integer_length) = length; println!("length is {} inches", integer_length); ``` - -上記の通り、 `let` を使って分解することで、標準のタプルと同じように内部の整数型を取り出すことができます。 -このケースでは `let Inches(integer_length)` が `integer_length` へ `10` を束縛します。 + + + +上記の通り `let` を使って分解することで、標準のタプルと同じように内部の整数型を取り出せます。 +このケースでは `let Inches(integer_length)` により `integer_length` へ `10` が束縛されます。 + +> 訳注: Rustには `type` 文もありますが、単に「型の別名」を定義するだけで、newtypeパターンのような「新しい型」は定義しません。 +> +> たとえば、`type` 文を使って、`i32` 型から `Inches` と `Meters` という2つの別名を定義した場合、コンパイラはこの2つの別名を同じ型として扱います。 +> つまり、本来 `Inches` の値を使う場所でうっかり `Meters` の値を使ってしまっても、コンパイルエラーになりません。 +> +> 一方で、これらを `Inches(i32)` と `Meters(i32)` というタプル構造体として定義した場合は、コンパイラは別の型として扱います。従って、もし使い間違えたときにはコンパイルエラーになってくれます。 # Unit-like 構造体 -あなたは全くメンバを持たない `struct` を定義できます。 +全くメンバを持たない `struct` も定義できます。 ```rust struct Electron; @@ -214,17 +281,20 @@ struct Electron; let x = Electron; ``` - -空のタプルである `()` は時々 `unit` と呼ばれ、それに似ていることからこのような構造体を `unit-like` と呼んでいます。タプル構造体のように、これは新しい型を定義します。 - - -これは単体でもごくまれに役立ちます(もっとも、時々型をマーク代わりとして役立てる程度です)が、他の機能と組み合わせることにより便利になります。例えば、ライブラリはあなたにイベントを処理できる特定の[トレイト][trait]が実装されたストラクチャの作成を要求するかもしれません。もしそのストラクチャの中に保存すべき値が何もなければ、あなたはダミーのデータを作成する必要はなく、ただunit-likeな `struct` を作るだけで良いのです。 + + + +空のタプルである `()` は時々 `unit` と呼ばれ、それに似ていることからこのような構造体を `unit-like` と呼んでいます。 +タプル構造体のように、これは新しい型を定義します。 + + + + + + + +これは単体でもごくまれに役立ちます(もっとも、時々型をマーク代わりとして役立てる程度です)が、他の機能と組み合わせることにより便利になります。 +例えば、ライブラリはあなたにイベントを処理できる特定の [トレイト][trait] を実装した構造体の作成を要求するかもしれません。 +もしその構造体に保存すべき値が何もなければ、あなたはダミーのデータを作成する必要はなく、unit-likeな `struct` を作れば良いのです。 [trait]: traits.html diff --git a/diff-1.6.0..1.9.0/src/doc/book/structs.md b/diff-1.6.0..1.9.0/src/doc/book/structs.md deleted file mode 100644 index 2e911e67..00000000 --- a/diff-1.6.0..1.9.0/src/doc/book/structs.md +++ /dev/null @@ -1,153 +0,0 @@ ---- a/src/doc/book/structs.md -+++ b/src/doc/book/structs.md -@@ -9,7 +9,8 @@ let origin_x = 0; - let origin_y = 0; - ``` - --A `struct` lets us combine these two into a single, unified datatype: -+A `struct` lets us combine these two into a single, unified datatype with `x` -+and `y` as field labels: - - ```rust - struct Point { -@@ -32,7 +33,7 @@ We can create an instance of our `struct` via `let`, as usual, but we use a `key - value` style syntax to set each field. The order doesn’t need to be the same as - in the original declaration. - --Finally, because fields have names, we can access the field through dot -+Finally, because fields have names, we can access them through dot - notation: `origin.x`. - - The values in `struct`s are immutable by default, like other bindings in Rust. -@@ -67,9 +68,8 @@ struct Point { - - Mutability is a property of the binding, not of the structure itself. If you’re - used to field-level mutability, this may seem strange at first, but it --significantly simplifies things. It even lets you make things mutable for a short --time only: -- -+significantly simplifies things. It even lets you make things mutable on a temporary -+basis: - - ```rust,ignore - struct Point { -@@ -82,12 +82,41 @@ fn main() { - - point.x = 5; - -- let point = point; // this new binding can’t change now -+ let point = point; // now immutable - - point.y = 6; // this causes an error - } - ``` - -+Your structure can still contain `&mut` pointers, which will let -+you do some kinds of mutation: -+ -+```rust -+struct Point { -+ x: i32, -+ y: i32, -+} -+ -+struct PointRef<'a> { -+ x: &'a mut i32, -+ y: &'a mut i32, -+} -+ -+fn main() { -+ let mut point = Point { x: 0, y: 0 }; -+ -+ { -+ let r = PointRef { x: &mut point.x, y: &mut point.y }; -+ -+ *r.x = 5; -+ *r.y = 6; -+ } -+ -+ assert_eq!(5, point.x); -+ assert_eq!(6, point.y); -+} -+``` -+ - # Update syntax - - A `struct` can include `..` to indicate that you want to use a copy of some -@@ -121,27 +150,24 @@ let point = Point3d { z: 1, x: 2, .. origin }; - # Tuple structs - - Rust has another data type that’s like a hybrid between a [tuple][tuple] and a --`struct`, called a ‘tuple struct’. Tuple structs have a name, but --their fields don’t: -+`struct`, called a ‘tuple struct’. Tuple structs have a name, but their fields -+don't. They are declared with the `struct` keyword, and then with a name -+followed by a tuple: -+ -+[tuple]: primitive-types.html#tuples - - ```rust - struct Color(i32, i32, i32); - struct Point(i32, i32, i32); --``` -- --[tuple]: primitive-types.html#tuples -- --These two will not be equal, even if they have the same values: - --```rust --# struct Color(i32, i32, i32); --# struct Point(i32, i32, i32); - let black = Color(0, 0, 0); - let origin = Point(0, 0, 0); - ``` -+Here, `black` and `origin` are not equal, even though they contain the same -+values. - --It is almost always better to use a `struct` than a tuple struct. We would write --`Color` and `Point` like this instead: -+It is almost always better to use a `struct` than a tuple struct. We -+would write `Color` and `Point` like this instead: - - ```rust - struct Color { -@@ -157,13 +183,14 @@ struct Point { - } - ``` - --Now, we have actual names, rather than positions. Good names are important, --and with a `struct`, we have actual names. -+Good names are important, and while values in a tuple struct can be -+referenced with dot notation as well, a `struct` gives us actual names, -+rather than positions. - --There _is_ one case when a tuple struct is very useful, though, and that’s a --tuple struct with only one element. We call this the ‘newtype’ pattern, because --it allows you to create a new type, distinct from that of its contained value --and expressing its own semantic meaning: -+There _is_ one case when a tuple struct is very useful, though, and that is when -+it has only one element. We call this the ‘newtype’ pattern, because -+it allows you to create a new type that is distinct from its contained value -+and also expresses its own semantic meaning: - - ```rust - struct Inches(i32); -@@ -175,7 +202,7 @@ println!("length is {} inches", integer_length); - ``` - - As you can see here, you can extract the inner integer type through a --destructuring `let`, just as with regular tuples. In this case, the -+destructuring `let`, as with regular tuples. In this case, the - `let Inches(integer_length)` assigns `10` to `integer_length`. - - # Unit-like structs -@@ -196,7 +223,7 @@ This is rarely useful on its own (although sometimes it can serve as a - marker type), but in combination with other features, it can become - useful. For instance, a library may ask you to create a structure that - implements a certain [trait][trait] to handle events. If you don’t have --any data you need to store in the structure, you can just create a -+any data you need to store in the structure, you can create a - unit-like `struct`. - - [trait]: traits.html -diff --git a/src/doc/book/syntax-and-semantics.md b/src/doc/book/syntax-and-semantics.md