1
+ <!--
1
2
# Splitting Borrows
3
+ -->
2
4
5
+ # 借用の分割
6
+
7
+ <!--
3
8
The mutual exclusion property of mutable references can be very limiting when
4
9
working with a composite structure. The borrow checker understands some basic
5
10
stuff, but will fall over pretty easily. It does understand structs
6
11
sufficiently to know that it's possible to borrow disjoint fields of a struct
7
12
simultaneously. So this works today:
13
+ -->
14
+
15
+ 可変参照の相互排他性は、複合構造体を使用している時に非常に制限を課してくる存在となります。
16
+ 借用チェッカはいくつか基本事項を理解していますが、本当に簡単にすっ転びます。
17
+ 借用チェッカは構造体について十分理解しているため、構造体の別々のフィールドを同時に借用することは可能です。
18
+ ですから、このコードは今日動作します。
8
19
9
20
``` rust
10
21
struct Foo {
@@ -23,8 +34,13 @@ let c2 = &x.c;
23
34
println! (" {} {} {} {}" , a , b , c , c2 );
24
35
```
25
36
37
+ <!--
26
38
However borrowck doesn't understand arrays or slices in any way, so this doesn't
27
39
work:
40
+ -->
41
+
42
+ しかし借用チェッカは、配列やスライスについてはどんな状況でも理解しないため、
43
+ このコードは動きません。
28
44
29
45
``` rust,ignore
30
46
let mut x = [1, 2, 3];
@@ -35,12 +51,15 @@ println!("{} {}", a, b);
35
51
36
52
``` text
37
53
<anon>:4:14: 4:18 error: cannot borrow `x[..]` as mutable more than once at a time
54
+ (エラー: 一度に `x[..]` を可変として 2 回以上借用することはできません)
38
55
<anon>:4 let b = &mut x[1];
39
56
^~~~
40
57
<anon>:3:14: 3:18 note: previous borrow of `x[..]` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `x[..]` until the borrow ends
58
+ (注釈: 以前の `x[..]` の借用はここで起きています。可変での借用は、その借用が終わるまで、その後のムーブや、借用、 `x[..]` の変更を防ぎます)
41
59
<anon>:3 let a = &mut x[0];
42
60
^~~~
43
61
<anon>:6:2: 6:2 note: previous borrow ends here
62
+ (注釈: 以前の借用はここで終了しています)
44
63
<anon>:1 fn main() {
45
64
<anon>:2 let mut x = [1, 2, 3];
46
65
<anon>:3 let a = &mut x[0];
@@ -49,19 +68,37 @@ println!("{} {}", a, b);
49
68
<anon>:6 }
50
69
^
51
70
error: aborting due to 2 previous errors
71
+ (エラー: 上記の 2 つのエラーのため中止)
52
72
```
53
73
74
+ <!--
54
75
While it was plausible that borrowck could understand this simple case, it's
55
76
pretty clearly hopeless for borrowck to understand disjointness in general
56
77
container types like a tree, especially if distinct keys actually *do* map
57
78
to the same value.
79
+ -->
80
+
81
+ 仮に借用チェッカがこの単純なケースを理解しても良さそうに見えるかもしれませんが、
82
+ 特に、異なるキーが* 本当に* 同じ値にマップされているときなど、
83
+ 木のような一般的なコンテナ内の、各値の素集合性を借用チェッカが理解することを望むのは、
84
+ 明らかに無駄です。
58
85
86
+ <!--
59
87
In order to "teach" borrowck that what we're doing is ok, we need to drop down
60
88
to unsafe code. For instance, mutable slices expose a `split_at_mut` function
61
89
that consumes the slice and returns two mutable slices. One for everything to
62
90
the left of the index, and one for everything to the right. Intuitively we know
63
91
this is safe because the slices don't overlap, and therefore alias. However
64
92
the implementation requires some unsafety:
93
+ -->
94
+
95
+ 借用チェッカに我々が行なっていることが問題ないと "教える" ためには、
96
+ アンセーフなコードに落とす必要があります。例えば、可変スライスには、
97
+ スライスを消費し 2 つの可変スライスを返す ` split_at_mut ` 関数を使用します。
98
+ 片方のスライスはインデックスの左側全てを、もう片方のスライスはインデックスの右側全てを
99
+ 使用するためのものです。直感的に、これは安全と分かります。互いのスライスが重ならなず、それゆえ
100
+ これらのスライスは元のスライスのエイリアスとなるからです。
101
+ しかし、その実装には少しアンセーフなコードを必要とします。
65
102
66
103
``` rust,ignore
67
104
fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
@@ -75,11 +112,21 @@ fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
75
112
}
76
113
```
77
114
115
+ <!--
78
116
This is actually a bit subtle. So as to avoid ever making two `&mut`'s to the
79
117
same value, we explicitly construct brand-new slices through raw pointers.
118
+ -->
119
+
120
+ これは実際、ちょっと微妙です。 同じ値に対する 2 つの ` &mut ` を生成するのを
121
+ 常に避けるため、生ポインタを通じて明確に完全に新しいスライスを構築します。
80
122
123
+ <!--
81
124
However more subtle is how iterators that yield mutable references work.
82
125
The iterator trait is defined as follows:
126
+ -->
127
+
128
+ しかし、もっと微妙なのは、可変参照を生成するイテレータが
129
+ どのように動作するかについてです。イテレータのトレイトは以下のように定義されます。
83
130
84
131
``` rust
85
132
trait Iterator {
@@ -89,25 +136,55 @@ trait Iterator {
89
136
}
90
137
```
91
138
139
+ <!--
92
140
Given this definition, Self::Item has *no* connection to `self`. This means that
93
141
we can call `next` several times in a row, and hold onto all the results
94
142
*concurrently*. This is perfectly fine for by-value iterators, which have
95
143
exactly these semantics. It's also actually fine for shared references, as they
96
144
admit arbitrarily many references to the same thing (although the iterator needs
97
145
to be a separate object from the thing being shared).
146
+ -->
147
+
148
+ 上記の定義によれば、 Self::Item は ` self ` と何のつながりも持ち* ません* 。
149
+ これは、 ` next ` を続けて何回か呼ぶことができ、そしてそれらに対する全ての結果を
150
+ * 同時に* 保持することができることを意味します。これは、値渡しのイテレータに対しては
151
+ 全く問題ありません。値渡しのイテレータも全く同じセマンティクスを持つからです。
152
+ そして、共有参照に対しても問題ありません。これらも同じものに対する任意の数の
153
+ 参照を認めているからです (イテレータは共有されるオブジェクトと分離されている必要がありますが) 。
98
154
155
+ <!--
99
156
But mutable references make this a mess. At first glance, they might seem
100
157
completely incompatible with this API, as it would produce multiple mutable
101
158
references to the same object!
159
+ -->
102
160
161
+ しかし、可変参照はこれをごちゃごちゃにします。ひと目見ただけでも、可変参照は
162
+ この API に全く対応できないように見えるかもしれません。この API が同じオブジェクトに対する
163
+ 複数の可変参照を生成するからです!
164
+
165
+ <!--
103
166
However it actually *does* work, exactly because iterators are one-shot objects.
104
167
Everything an IterMut yields will be yielded at most once, so we don't
105
168
actually ever yield multiple mutable references to the same piece of data.
169
+ -->
170
+
171
+ しかし、この API は* 本当に* 動作します。まさにイテレータがその場限りのオブジェクトであるからです。
172
+ IterMut が生成するすべてのものは高々 1 回しか生成されません。ですから実際には、
173
+ 常に、何らかのひとかけらのデータに対する可変参照を、複数回生成していないのです。
106
174
175
+ <!--
107
176
Perhaps surprisingly, mutable iterators don't require unsafe code to be
108
177
implemented for many types!
178
+ -->
109
179
180
+ もしかすると驚くかもしれませんが、可変のイテレータは多くの型に対して
181
+ 実装する際、アンセーフなコードを必要としないのです!
182
+
183
+ <!--
110
184
For instance here's a singly linked list:
185
+ -->
186
+
187
+ 例えばこれは、片方向リストです。
111
188
112
189
``` rust
113
190
# fn main () {}
@@ -142,7 +219,11 @@ impl<'a, T> Iterator for IterMut<'a, T> {
142
219
}
143
220
```
144
221
222
+ <!--
145
223
Here's a mutable slice:
224
+ -->
225
+
226
+ これは可変スライスです。
146
227
147
228
``` rust
148
229
# fn main () {}
@@ -176,7 +257,11 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
176
257
}
177
258
```
178
259
260
+ <!--
179
261
And here's a binary tree:
262
+ -->
263
+
264
+ そしてこれは二分木です。
180
265
181
266
``` rust
182
267
# fn main () {}
@@ -284,8 +369,16 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
284
369
}
285
370
```
286
371
372
+ <!--
287
373
All of these are completely safe and work on stable Rust! This ultimately
288
374
falls out of the simple struct case we saw before: Rust understands that you
289
375
can safely split a mutable reference into subfields. We can then encode
290
376
permanently consuming a reference via Options (or in the case of slices,
291
377
replacing with an empty slice).
378
+ -->
379
+
380
+ これらは全て、完全に安全で、安定版の Rust で動作します! これは究極には、
381
+ 前に見た単純な構造体のケースから外れています。すなわち、 Rust は、
382
+ 可変参照を複数の副フィールドに安全に分割できると理解しているのです。
383
+ ですから Option を通じて、参照を消費することで、永続的にエンコードすることができます。
384
+ (あるいはスライスの場合、空のスライスで置き換えます)
0 commit comments