diff --git a/1.6/ja/book/mutability.md b/1.6/ja/book/mutability.md index 71acb551..2bb157a9 100644 --- a/1.6/ja/book/mutability.md +++ b/1.6/ja/book/mutability.md @@ -1,30 +1,39 @@ -% Mutability +% ミュータビリティ + -Mutability, the ability to change something, works a bit differently in Rust -than in other languages. The first aspect of mutability is its non-default -status: + + + +Rustにおけるミュータビリティ、何かを変更する能力は、他のプログラミング言語とはすこし異なっています。 +ミュータビリティの一つ目の特徴は、それがデフォルトでは無いという点です: ```rust,ignore let x = 5; -x = 6; // error! +# // x = 6; // error! +x = 6; // エラー! ``` -We can introduce mutability with the `mut` keyword: + +`mut` キーワードによりミュータビリティを導入できます: ```rust let mut x = 5; -x = 6; // no problem! +# // x = 6; // no problem! +x = 6; // 問題なし! ``` -This is a mutable [variable binding][vb]. When a binding is mutable, it means -you’re allowed to change what the binding points to. So in the above example, -it’s not so much that the value at `x` is changing, but that the binding -changed from one `i32` to another. + + + + +これはミュータブルな [変数束縛][vb] です。束縛がミュータブルであるとき、その束縛が何を指すかを変更して良いことを意味します。 +つまり上記の例では、`x` の値を変更したのではなく、ある `i32` から別の値へと束縛が変わったのです。 [vb]: variable-bindings.html -If you want to change what the binding points to, you’ll need a [mutable reference][mr]: + +束縛が指す先を変更する場合は、[ミュータブル参照][mr] を使う必要があるでしょう: ```rust let mut x = 5; @@ -33,22 +42,28 @@ let y = &mut x; [mr]: references-and-borrowing.html -`y` is an immutable binding to a mutable reference, which means that you can’t -bind `y` to something else (`y = &mut z`), but you can mutate the thing that’s -bound to `y` (`*y = 5`). A subtle distinction. + + + +`y` はミュータブル参照へのイミュータブルな束縛であり、 `y` を他の束縛に変える(`y = &mut z`)ことはできません。 +しかし、`y` に束縛されているものを変化させること(`*y = 5`)は可能です。微妙な区別です。 -Of course, if you need both: + +もちろん、両方が必要ならば: ```rust let mut x = 5; let mut y = &mut x; ``` -Now `y` can be bound to another value, and the value it’s referencing can be -changed. + + +今度は `y` が他の値を束縛することもできますし、参照している値を変更することもできます。 -It’s important to note that `mut` is part of a [pattern][pattern], so you -can do things like this: + + +`mut` は [パターン][pattern] の一部を成すことに十分注意してください。 +つまり、次のようなことが可能です: ```rust let (mut x, y) = (5, 6); @@ -59,11 +74,14 @@ fn foo(mut x: i32) { [pattern]: patterns.html -# Interior vs. Exterior Mutability + +# 内側 vs. 外側のミュータビリティ -However, when we say something is ‘immutable’ in Rust, that doesn’t mean that -it’s not able to be changed: we mean something has ‘exterior mutability’. Consider, -for example, [`Arc`][arc]: + + + +一方で、Rustで「イミュータブル(immutable)」について言及するとき、変更不可能であることを意味しない: +「外側のミュータビリティ(exterior mutability)」を表します。例として、[`Arc`][arc] を考えます: ```rust use std::sync::Arc; @@ -74,30 +92,46 @@ let y = x.clone(); [arc]: ../std/sync/struct.Arc.html -When we call `clone()`, the `Arc` needs to update the reference count. Yet -we’ve not used any `mut`s here, `x` is an immutable binding, and we didn’t take -`&mut 5` or anything. So what gives? - -To understand this, we have to go back to the core of Rust’s guiding -philosophy, memory safety, and the mechanism by which Rust guarantees it, the -[ownership][ownership] system, and more specifically, [borrowing][borrowing]: - -> You may have one or the other of these two kinds of borrows, but not both at -> the same time: + + + +`clone()` を呼び出すとき、`Arc` は参照カウントを更新する必要があります。しかし、 +ここでは `mut` を一切使っていません。つまり `x` はイミュータブルな束縛であり、 +`&mut 5` のような引数もとりません。一体どうなっているの? + + + + +これを理解するには、Rust言語の設計哲学の中心をなすメモリ安全性と、Rustがそれを保証するメカニズムである [所有権][ownership] システム、 +特に [借用][borrowing] に立ち返る必要があります。 + + + + + + +> 次の2種類の借用のどちらか1つを持つことはありますが、両方を同時に持つことはありません。 > -> * one or more references (`&T`) to a resource, -> * exactly one mutable reference (`&mut T`). +> * リソースに対する1つ以上の参照(`&T`) +> * ただ1つのミュータブルな参照(`&mut T`) [ownership]: ownership.html [borrowing]: references-and-borrowing.html#borrowing -So, that’s the real definition of ‘immutability’: is this safe to have two -pointers to? In `Arc`’s case, yes: the mutation is entirely contained inside -the structure itself. It’s not user facing. For this reason, it hands out `&T` -with `clone()`. If it handed out `&mut T`s, though, that would be a problem. - -Other types, like the ones in the [`std::cell`][stdcell] module, have the -opposite: interior mutability. For example: + + + + +つまり、「イミュータビリティ」の真の定義はこうです: これは2箇所から指されても安全ですか? +`Arc` の例では、イエス: 変更は完全にそれ自身の構造の内側で行われます。ユーザからは見えません。 +このような理由により、 `clone()` を用いて `T&` を配るのです。仮に `&mut T` を配ってしまうと、 +問題になるでしょう。 +(訳注: `Arc`を用いて複数スレッドにイミュータブル参照を配布し、スレッド間でオブジェクトを共有できます。) + + + +[`std::cell`][stdcell] モジュールにあるような別の型では、反対の性質: 内側のミュータビリティ(interior mutability)を持ちます。 +例えば: ```rust use std::cell::RefCell; @@ -109,8 +143,10 @@ let y = x.borrow_mut(); [stdcell]: ../std/cell/index.html -RefCell hands out `&mut` references to what’s inside of it with the -`borrow_mut()` method. Isn’t that dangerous? What if we do: + + +RefCellでは `borrow_mut()` メソッドによって、その内側にある値への `&mut` 参照を配ります。 +それって危ないのでは? もし次のようにすると: ```rust,ignore use std::cell::RefCell; @@ -122,25 +158,35 @@ let z = x.borrow_mut(); # (y, z); ``` -This will in fact panic, at runtime. This is what `RefCell` does: it enforces -Rust’s borrowing rules at runtime, and `panic!`s if they’re violated. This -allows us to get around another aspect of Rust’s mutability rules. Let’s talk -about it first. + + + + +実際に、このコードは実行時にパニックするでしょう。これが `RefCell` が行うことです: +Rustの借用ルールを実行時に強制し、違反したときには `panic!` を呼び出します。 +これによりRustのミュータビリティ・ルールのもう一つの特徴を回避できるようになります。 +最初に見ていきましょう。 + + +## フィールド・レベルのミュータビリティ -## Field-level mutability + + + +ミュータビリティとは、借用(`&mut`)や束縛(`let mut`)に関する属性です。これが意味するのは、 +例えば、一部がミュータブルで一部がイミュータブルなフィールドを持つ [`struct`][struct] は作れないということです。 -Mutability is a property of either a borrow (`&mut`) or a binding (`let mut`). -This means that, for example, you cannot have a [`struct`][struct] with -some fields mutable and some immutable: ```rust,ignore struct Point { x: i32, - mut y: i32, // nope +# // mut y: i32, // nope + mut y: i32, // ダメ } ``` -The mutability of a struct is in its binding: + +構造体のミュータビリティは、それへの束縛の一部です。 ```rust,ignore struct Point { @@ -154,12 +200,14 @@ a.x = 10; let b = Point { x: 5, y: 6}; -b.x = 10; // error: cannot assign to immutable field `b.x` +# // b.x = 10; // error: cannot assign to immutable field `b.x` +b.x = 10; // エラー: イミュータブルなフィールド `b.x` へ代入できない ``` [struct]: structs.html -However, by using [`Cell`][cell], you can emulate field-level mutability: + +しかし、[`Cell`][cell] を使えば、フィールド・レベルのミュータビリティをエミュレートできます。 ```rust use std::cell::Cell; @@ -178,4 +226,5 @@ println!("y: {:?}", point.y); [cell]: ../std/cell/struct.Cell.html -This will print `y: Cell { value: 7 }`. We’ve successfully updated `y`. + +このコードは `y: Cell { value: 7 }` と表示するでしょう。ちゃんと `y` を更新できました。 diff --git a/TranslationTable.md b/TranslationTable.md index a929c5cd..07e22e4f 100644 --- a/TranslationTable.md +++ b/TranslationTable.md @@ -69,6 +69,7 @@ | error | エラー | error handling | エラーハンドリング | expression statement | 式文 +| exterior | 外側の | feature | フィーチャ | foreign | 他言語 | free-standing function | フリースタンディングな関数 @@ -79,9 +80,11 @@ | hash | ハッシュ | identifier | 識別子 | immutable | イミュータブル +| immutability | イミュータビリティ | implement | 実装する | initialize | 初期化する | input lifetime | 入力ライフタイム +| interior | 内側の | install | インストール | installer | インストーラ | interpolate | インターポーレートする @@ -133,6 +136,7 @@ | return | 返す | return type | リターン型 | return value | 戻り値 +| runtime | 実行時 | safe | 安全 | safety check | 安全性検査 | scope | スコープ