Skip to content

Commit 5a9d826

Browse files
authored
Merge pull request #165 from tatsuya6502/ownership-1.9
4.8. Ownership (1.9)
2 parents 3f6a1ba + 2b92acd commit 5a9d826

File tree

2 files changed

+130
-154
lines changed

2 files changed

+130
-154
lines changed

1.9/ja/book/ownership.md

Lines changed: 130 additions & 42 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,47 @@ 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
91-
[heap]: the-stack-and-the-heap.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#配列
109+
[vectors]: vectors.html
110+
<!-- 訳注:原文では[heap]のリンク先が単に the-stack-and-the-heap.html となっていますが、 -->
111+
<!-- [stack]に合わせて、#ヒープ を追加しました -->
112+
[heap]: the-stack-and-the-heap.html#ヒープ
113+
[stack]: the-stack-and-the-heap.html#スタック
92114
[bindings]: variable-bindings.html
115+
[generics]: generics.html
93116

94117
<!-- # Move semantics -->
95118
# ムーブセマンティクス
96119

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

103126
```rust
@@ -118,7 +141,7 @@ println!("v[0] is: {}", v[0]);
118141
```
119142

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

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

154177
<!-- ## The details -->
155178
## 詳細
156179

157180
<!-- 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-
このようなコードを書いたとします。
181+
<!-- important. -->
182+
束縛をムーブした後で、それを使うことができないと言いました。
183+
その理由は、ごく詳細かもしれませんが、とても重要です。
184+
185+
<!-- When we write code like this: -->
186+
このようなコードを書いた時、
187+
188+
```rust
189+
let x = 10;
190+
```
191+
192+
<!-- Rust allocates memory for an integer [i32] on the [stack][sh], copies the bit -->
193+
<!-- pattern representing the value of 10 to the allocated memory and binds the -->
194+
<!-- variable name x to this memory region for future reference. -->
195+
Rustは [スタック][sh] 上に整数 [i32] のためのメモリを割り当て、そこに、10という値を表すビットパターンをコピーします。
196+
そして後から参照できるよう、変数名xをこのメモリ領域に束縛します。
197+
198+
<!-- 訳注:原文ではi32へのリンクが抜けているので、ここに追加しました -->
199+
[i32]: primitive-types.html#数値型
200+
201+
<!-- Now consider the following code fragment: -->
202+
今度は、こんなコード片について考えてみましょう。
161203

162204
```rust
163205
let v = vec![1, 2, 3];
164206

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

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` の使用を禁止するのです。
253+
<!-- and `v1` were still accessible we'd end up with an invalid vector since `v1` -->
254+
<!-- would not know that the heap data has been truncated. Now, the part of the -->
255+
<!-- vector `v1` on the stack does not agree with the corresponding part on the -->
256+
<!-- heap. `v1` still thinks there are three elements in the vector and will -->
257+
<!-- happily let us access the non existent element `v1[2]` but as you might -->
258+
<!-- already know this is a recipe for disaster. Especially because it might lead -->
259+
<!-- to a segmentation fault or worse allow an unauthorized user to read from -->
260+
<!-- memory to which they don't have access. -->
261+
もしまだ `v1` にアクセスできたとしたら、`v1` はヒープデータが切り詰められたことを知らないので、不正なベクタを提供することになってしまいます。
262+
ここでスタック上の `v1` は、ヒープ上で対応する相手と一貫性が取れていません。
263+
`v1` はベクタにまだ3つの要素があると思っているので、もし私たちが存在しない要素 `v1[2]` にアクセスしようとしたら、喜んでそうさせるでしょう。
264+
しかし、すでにお気づきの通り、特に次のような理由から大惨事に繋がるかもしれません。
265+
これはセグメンテーション違反を起こすかもしれませんし、最悪の場合、権限を持たないユーザーが、本来アクセスできないはずのメモリを読めてしまうかもしれないのです。
266+
267+
<!-- This is why Rust forbids using `v` after we’ve done the move. -->
268+
このような理由から、Rustはムーブを終えた後の `v` の使用を禁止するのです。
181269

182270
[sh]: the-stack-and-the-heap.html
183271

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

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

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

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

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

290378
```rust
291379
fn foo(v1: Vec<i32>, v2: Vec<i32>) -> (Vec<i32>, Vec<i32>, i32) {
@@ -305,10 +393,10 @@ let (v1, v2, answer) = foo(v1, v2);
305393

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

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

0 commit comments

Comments
 (0)