Skip to content

Commit f0dab6a

Browse files
committed
Update Ownership to 1.9
1 parent 1819a56 commit f0dab6a

File tree

1 file changed

+124
-41
lines changed

1 file changed

+124
-41
lines changed

1.9/ja/book/ownership.md

Lines changed: 124 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@
3939
<!-- is _done at compile time_. You do not pay any run-time cost for any of these -->
4040
<!-- features. -->
4141
Rustは安全性とスピートに焦点を合わせます。
42-
Rustはそれらの目標をたくさんの「ゼロコスト抽象化」を通じて成し遂げます。それは、Rustでは抽象化を機能させるためのコストをできる限り小さくすることを意味します。
42+
Rustはそれらの目標を、様々な「ゼロコスト抽象化」を通じて成し遂げます。
43+
それは、Rustでは抽象化を機能させるためのコストをできる限り小さくすることを意味します。
4344
所有権システムはゼロコスト抽象化の主な例です。
4445
このガイドの中で話すであろう解析の全ては _コンパイル時に行われます_
4546
それらのどの機能に対しても実行時のコストは全く掛かりません。
@@ -54,9 +55,11 @@ Rustはそれらの目標をたくさんの「ゼロコスト抽象化」を通
5455
<!-- rules of the ownership system for a period of time, they fight the borrow -->
5556
<!-- checker less and less. -->
5657
しかし、このシステムはあるコストを持ちます。それは学習曲線です。
57-
多くの新しいRustのユーザは「借用チェッカとの戦い」と好んで呼ばれるものを経験します。そこではRustコンパイラが開発者が正しいと考えるプログラムをコンパイルすることを拒絶します。
58+
多くのRust入門者は、私たちが「借用チェッカとの戦い」と呼ぶものを経験します。
59+
そこではRustコンパイラが、開発者が正しいと考えるプログラムをコンパイルすることを拒絶します。
5860
所有権がどのように機能するのかについてのプログラマのメンタルモデルがRustの実装する実際のルールにマッチしないため、これはしばしば起きます。
59-
しかし、よいニュースがあります。より経験豊富なRustの開発者は次のことを報告します。一度彼らが所有権システムのルールとともにしばらく仕事をすれば、彼らが借用チェッカと戦うことは少なくなっていくということです。
61+
しかし、よいニュースがあります。より経験豊富なRustの開発者は次のことを報告します。
62+
それは、所有権システムのルールと共にしばらく仕事をすれば、借用チェッカと戦うことは次第に少なくなっていく、というものです。
6063

6164
<!-- With that in mind, let’s learn about ownership. -->
6265
それを念頭に置いて、所有権について学びましょう。
@@ -77,27 +80,45 @@ fn foo() {
7780
}
7881
```
7982

80-
<!-- When `v` comes into scope, a new [`Vec<T>`][vect] is created. In this case, the -->
81-
<!-- vector also allocates space on [the heap][heap], for the three elements. When -->
82-
<!-- `v` goes out of scope at the end of `foo()`, Rust will clean up everything -->
83-
<!-- related to the vector, even the heap-allocated memory. This happens -->
84-
<!-- deterministically, at the end of the scope. -->
85-
`v` がスコープに入るとき、新しい [`Vec<T>`][vect] が作られます
86-
この場合、ベクタも3つの要素のために [ヒープ][heap] に空間を割り当てます
87-
`foo()` の最後で `v` がスコープから外れるとき、Rustはベクタに関連するもの全てを取り除くでしょう。それがヒープ割当てのメモリであってもです
83+
<!-- When `v` comes into scope, a new [vector][vectors] is created on [the stack][stack], -->
84+
<!-- and it allocates space on [the heap][heap] for its elements. When `v` goes out -->
85+
<!-- of scope at the end of `foo()`, Rust will clean up everything related to the -->
86+
<!-- vector, even the heap-allocated memory. This happens deterministically, at the -->
87+
<!-- end of the scope. -->
88+
`v` がスコープに入るとき、新しい [ベクタ][vectors][スタック][stack] 上に作られ、要素を格納するために [ヒープ][heap] に空間を割り当てます
89+
`foo()` の最後で `v` がスコープから外れるとき、Rustはベクタに関連するもの全てを取り除くでしょう
90+
それがヒープ割り当てのメモリであってもです
8891
これはスコープの最後で決定的に起こります。
8992

90-
[vect]: ../std/vec/struct.Vec.html
93+
<!-- We'll cover [vectors] in detail later in this chapter; we only use them -->
94+
<!-- here as an example of a type that allocates space on the heap at runtime. They -->
95+
<!-- behave like [arrays], except their size may change by `push()`ing more -->
96+
<!-- elements onto them. -->
97+
<!-- 訳注:"We'll cover [vectors] in detail later..." となっていますが、 -->
98+
<!-- ベクタはこのセクションより前に説明されていますので、それに合わせて訳を変更しました。 -->
99+
[ベクタ][vectors] については、前のセクションで説明済みですが、簡単に復習しましょう。
100+
ここではベクタを、実行時にヒープに空間を割り当てる型の例として用いています。
101+
ベクタは [配列][arrays] のように振る舞いますが、追加の要素を `push()` するとサイズが変わるところは違います。
102+
103+
<!-- Vectors have a [generic type][generics] `Vec<T>`, so in this example `v` will have type -->
104+
<!-- `Vec<i32>`. We'll cover generics in detail later in this chapter. -->
105+
ベクタは [ジェネリクス型][generics] `Vec<T>` を持ちますので、この例における `v``Vec<i32>` 型になるでしょう。
106+
ジェネリクスについては、この章の後の方で詳しく説明します。
107+
108+
[arrays]: primitive-types.html#arrays
109+
[vectors]: vectors.html
91110
[heap]: the-stack-and-the-heap.html
111+
[stack]: the-stack-and-the-heap.html#the-stack
92112
[bindings]: variable-bindings.html
113+
[generics]: generics.html
93114

94115
<!-- # Move semantics -->
95116
# ムーブセマンティクス
96117

97118
<!-- There’s some more subtlety here, though: Rust ensures that there is _exactly -->
98119
<!-- one_ binding to any given resource. For example, if we have a vector, we can -->
99120
<!-- assign it to another binding: -->
100-
しかし、ここではもっと微妙なことがあります。それは、Rustは与えられたリソースに対する束縛が _1つだけ_ あるということを保証するということです
121+
しかし、ここではもっと些細に見えることがあります。それは、Rustは与えられたリソースに対する束縛が _1つだけ_ あることを保証するというものです
101122
例えば、もしベクタがあれば、それを別の束縛に割り当てることはできます。
102123

103124
```rust
@@ -118,7 +139,7 @@ println!("v[0] is: {}", v[0]);
118139
```
119140

120141
<!-- It looks like this: -->
121-
それはこのように見えます
142+
こんな感じのエラーです
122143

123144
```text
124145
error: use of moved value: `v`
@@ -148,44 +169,106 @@ println!("v[0] is: {}", v[0]);
148169
<!-- special annotation here, it’s the default thing that Rust does. -->
149170
「use of moved value」という同じエラーです。
150171
所有権を何か別のものに転送するとき、参照するものを「ムーブした」と言います。
151-
ここでは特別な種類の注釈を必要としません
152-
それはRustの行うデフォルトの動作です
172+
これは特別な種類の注釈なしに行われます
173+
つまりRustのデフォルトの動作です
153174

154175
<!-- ## The details -->
155176
## 詳細
156177

157178
<!-- The reason that we cannot use a binding after we’ve moved it is subtle, but -->
158-
<!-- important. When we write code like this: -->
159-
束縛をムーブした後ではそれを使うことができないということの理由は微妙ですが重要です。
160-
このようなコードを書いたとします。
179+
<!-- important. -->
180+
束縛をムーブした後で、それを使うことができないと言いました。
181+
その理由は、ごく詳細かもしれませんが、とても重要です。
182+
183+
<!-- When we write code like this: -->
184+
このようなコードを書いた時、
185+
186+
```rust
187+
let x = 10;
188+
```
189+
190+
<!-- Rust allocates memory for an integer [i32] on the [stack][sh], copies the bit -->
191+
<!-- pattern representing the value of 10 to the allocated memory and binds the -->
192+
<!-- variable name x to this memory region for future reference. -->
193+
Rustは [スタック][sh] 上に整数 [i32] のためのメモリを割り当て、そこに、10という値を表すビットパターンをコピーします。
194+
そして後から参照できるよう、変数名xをこのメモリ領域に束縛します。
195+
196+
<!-- Now consider the following code fragment: -->
197+
今度は、こんなコード片について考えてみましょう。
161198

162199
```rust
163200
let v = vec![1, 2, 3];
164201

165-
let v2 = v;
202+
let mut v2 = v;
203+
```
204+
205+
<!-- The first line allocates memory for the vector object `v` on the stack like -->
206+
<!-- it does for `x` above. But in addition to that it also allocates some memory -->
207+
<!-- on the [heap][sh] for the actual data (`[1, 2, 3]`). Rust copies the address -->
208+
<!-- of this heap allocation to an internal pointer, which is part of the vector -->
209+
<!-- object placed on the stack (let's call it the data pointer). -->
210+
<!-- 訳注:ここで "data pointer" という言葉を導入してますが、後で使っていないので、訳は省きました。-->
211+
<!-- 訳注:allocation ですが、「割り当て」だと不自然な所は、「領域(region)」と訳しました。 -->
212+
最初の行では、先ほどの `x` と同様に、ベクタオブジェクト `v` のために、スタック上にメモリを割り当てます。
213+
しかし、これに加えて、実際のデータ( `[1, 2, 3]` )のために、 [ヒープ][sh] 上にもメモリを割り当てます。
214+
スタック上のベクタオブジェクトの中にはポインタがあり、Rustはいま割り当てたヒープのアドレスをそこへコピーします。
215+
216+
<!-- It is worth pointing out (even at the risk of stating the obvious) that the -->
217+
<!-- vector object and its data live in separate memory regions instead of being a -->
218+
<!-- single contiguous memory allocation (due to reasons we will not go into at -->
219+
<!-- this point of time). These two parts of the vector (the one on the stack and -->
220+
<!-- one on the heap) must agree with each other at all times with regards to -->
221+
<!-- things like the length, capacity etc. -->
222+
すでに分かりきっているかもしれませんが、念のためここで確認しておきたいのは、ベクタオブジェクトとそのデータは、それぞれが別のメモリ領域に格納されていることです。
223+
決してそれらは、1つの連続したメモリ領域に置かれているわけではありません(その理由についての詳細は、いまは省きます)。
224+
そして、ベクタにおけるこれら2つの部分(スタック上のものと、ヒープ上のもの)は、要素数やキャパシティ(容量)などについて、常にお互いの間で一貫性が保たれている必要があります。
225+
226+
<!-- When we move `v` to `v2`, Rust actually does a bitwise copy of the vector -->
227+
<!-- object `v` into the stack allocation represented by `v2`. This shallow copy -->
228+
<!-- does not create a copy of the heap allocation containing the actual data. -->
229+
<!-- Which means that there would be two pointers to the contents of the vector -->
230+
<!-- both pointing to the same memory allocation on the heap. It would violate -->
231+
<!-- Rust’s safety guarantees by introducing a data race if one could access both -->
232+
<!-- `v` and `v2` at the same time. -->
233+
`v``v2` にムーブするときRustが実際に行うのは、ビット単位のコピーを使って、ベクタオブジェクト `v` が示すスタック領域の情報を、 `v2` が示すスタック領域へコピーすることです。
234+
この浅いコピーでは、実際のデータを格納しているヒープ領域はコピーしません。
235+
これはベクタに格納されたデータとして、ヒープ上の同一のメモリ領域を指すポインタが、2つできてしまうことを意味します。
236+
もし誰かが `v``v2` に同時にアクセスしたら?
237+
これはデータ競合を持ち込むことになり、Rustの安全性保証に違反するでしょう。
238+
239+
<!-- For example if we truncated the vector to just two elements through `v2`: -->
240+
例えば `v2` を通して、ベクタを2要素分、切り詰めたとしましょう。
241+
242+
```rust
243+
# let v = vec![1, 2, 3];
244+
# let mut v2 = v;
245+
v2.truncate(2);
166246
```
167247

168-
<!-- The first line allocates memory for the vector object, `v`, and for the data it -->
169-
<!-- contains. The vector object is stored on the [stack][sh] and contains a pointer -->
170-
<!-- to the content (`[1, 2, 3]`) stored on the [heap][sh]. When we move `v` to `v2`, -->
171-
<!-- it creates a copy of that pointer, for `v2`. Which means that there would be two -->
172-
<!-- pointers to the content of the vector on the heap. It would violate Rust’s -->
173-
<!-- safety guarantees by introducing a data race. Therefore, Rust forbids using `v` -->
174-
<!-- after we’ve done the move. -->
175-
最初の行はベクタオブジェクト `v` とそれの含むデータのためのメモリを割り当てます。
176-
ベクタオブジェクトは [スタック][sh] に保存され、 [ヒープ][sh] に保存された内容( `[1, 2, 3]` )へのポインタを含みます。
177-
`v``v2` にムーブするとき、それは `v2` のためにそのポインタのコピーを作ります。
178-
それは、ヒープ上のベクタの内容へのポインタが2つあることを意味します。
179-
それはデータ競合を持ち込むことでRustの安全性保証に違反するでしょう。
180-
そのため、Rustはムーブを終えた後の `v` の使用を禁止するのです。
248+
<!-- and `v1` were still accessible we'd end up with an invalid vector since `v1` -->
249+
<!-- would not know that the heap data has been truncated. Now, the part of the -->
250+
<!-- vector `v1` on the stack does not agree with the corresponding part on the -->
251+
<!-- heap. `v1` still thinks there are three elements in the vector and will -->
252+
<!-- happily let us access the non existent element `v1[2]` but as you might -->
253+
<!-- already know this is a recipe for disaster. Especially because it might lead -->
254+
<!-- to a segmentation fault or worse allow an unauthorized user to read from -->
255+
<!-- memory to which they don't have access. -->
256+
もしまだ `v1` にアクセスできたとしたら、`v1` はヒープデータが切り詰められたことを知らないので、不正なベクタを提供することになってしまいます。
257+
ここでスタック上の `v1` は、ヒープ上で対応する相手と一貫性が取れていません。
258+
`v1` はベクタにまだ3つの要素があると思っているので、もし私たちが存在しない要素 `v1[2]` にアクセスしようとしたら、喜んでそうさせるでしょう。
259+
しかし、すでにお気づきの通り、特に次のような理由から大惨事に繋がるかもしれません。
260+
これはセグメンテーション違反を起こすかもしれませんし、最悪の場合、権限を持たないユーザーが、本来アクセスできないはずのメモリを読めてしまうかもしれないのです。
261+
262+
<!-- This is why Rust forbids using `v` after we’ve done the move. -->
263+
このような理由から、Rustはムーブを終えた後の `v` の使用を禁止するのです。
181264

182265
[sh]: the-stack-and-the-heap.html
183266

184267
<!-- It’s also important to note that optimizations may remove the actual copy of -->
185268
<!-- the bytes on the stack, depending on circumstances. So it may not be as -->
186269
<!-- inefficient as it initially seems. -->
187-
最適化が状況によってはスタック上のバイトの実際のコピーを削除するかもしれないことに気付くことも重要です
188-
そのため、それは最初に思ったほど非効率ではないかもしれません
270+
また知っておいてほしいのは、状況によっては最適化により、スタック上のバイトを実際にコピーする処理が省かれる可能性があることです
271+
そのため、ムーブは最初に思ったほど非効率ではないかもしれません
189272

190273
<!-- ## `Copy` types -->
191274
## `Copy`
@@ -197,7 +280,7 @@ let v2 = v;
197280
<!-- behavior. For example: -->
198281
所有権が他の束縛に転送されるとき、元の束縛を使うことができないということを証明しました。
199282
しかし、この挙動を変更する [トレイト][traits] があります。それは `Copy` と呼ばれます。
200-
トレイトについてはまだ議論していませんが、とりあえずそれらを挙動を追加するある型への注釈として考えることができます
283+
トレイトについてはまだ議論していませんが、とりあえずそれらを、ある型に対してある挙動を追加するための、注釈のようなものとして考えて構いません
201284
例えばこうです。
202285

203286
```rust
@@ -213,8 +296,8 @@ println!("v is: {}", v);
213296
<!-- But, unlike a move, we can still use `v` afterward. This is because an `i32` -->
214297
<!-- has no pointers to data somewhere else, copying it is a full copy. -->
215298
この場合、 `v``i32` で、それは `Copy` トレイトを実装します。
216-
これはちょうどムーブと同じように、 `v``v2` に割り当てるとき、データのコピーが作られるということを意味します
217-
しかし、ムーブと違って後でまだ `v` を使うことができます。
299+
これはちょうどムーブと同じように、 `v``v2` に代入するとき、データのコピーが作られることを意味します
300+
しかし、ムーブと違って、後でまだ `v` を使うことができます。
218301
これは `i32` がどこか別の場所へのポインタを持たず、コピーが完全コピーだからです。
219302

220303
<!-- All primitive types implement the `Copy` trait and their ownership is -->
@@ -285,7 +368,7 @@ fn foo(v: Vec<i32>) -> Vec<i32> {
285368

286369
<!-- This would get very tedious. It gets worse the more things we want to take ownership of: -->
287370
これは非常に退屈になるでしょう。
288-
もっとたくさんのものの所有権を受け取れば、それはもっとひどくなります
371+
もっとたくさんのものの所有権を受け取ろうとすると、状況はさらに悪化します
289372

290373
```rust
291374
fn foo(v1: Vec<i32>, v2: Vec<i32>) -> (Vec<i32>, Vec<i32>, i32) {
@@ -305,10 +388,10 @@ let (v1, v2, answer) = foo(v1, v2);
305388

306389
<!-- Ugh! The return type, return line, and calling the function gets way more -->
307390
<!-- complicated. -->
308-
うわあ!
391+
うわあ
309392
戻り値の型、リターン行、関数呼出しがもっと複雑になります。
310393

311394
<!-- Luckily, Rust offers a feature, borrowing, which helps us solve this problem. -->
312395
<!-- It’s the topic of the next section! -->
313396
幸運なことに、Rustは借用という機能を提供します。それはこの問題を解決するために手助けしてくれます。
314-
それが次のセクションの話題です!
397+
それが次のセクションの話題です

0 commit comments

Comments
 (0)