Skip to content

Commit dd0f890

Browse files
コード中の訳を、併記する形に変更
1 parent bd5a4f3 commit dd0f890

File tree

1 file changed

+15
-93
lines changed

1 file changed

+15
-93
lines changed

src/rust-2021/disjoint-capture-in-closures.md

Lines changed: 15 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -45,21 +45,14 @@ Rust 2018 以前では、クロージャに使われているのが1つのフィ
4545
例えば、 `|| a.x + 1``a.x` への参照だけでなく、`a` への参照をキャプチャします。
4646
`a` 全体がキャプチャされると、`a` の他のフィールドの値を書き換えたりムーブしたりできなくなります。従って以下のようなコードはコンパイルに失敗します:
4747

48-
<!--
4948
```rust,ignore
5049
let a = SomeStruct::new();
5150
drop(a.x); // Move out of one field of the struct
51+
// 構造体のフィールドの1つをムーブする
5252
println!("{}", a.y); // Ok: Still use another field of the struct
53+
// OK: 構造体の他のフィールドは、まだ使える
5354
let c = || println!("{}", a.y); // Error: Tries to capture all of `a`
54-
c();
55-
```
56-
-->
57-
58-
```rust,ignore
59-
let a = SomeStruct::new();
60-
drop(a.x); // 構造体のフィールドの1つをムーブする
61-
println!("{}", a.y); // OK: 構造体の他のフィールドは、まだ使える
62-
let c = || println!("{}", a.y); // エラー: `a` 全体をキャプチャしようとする
55+
// エラー: `a` 全体をキャプチャしようとする
6356
c();
6457
```
6558

@@ -127,25 +120,14 @@ Whenever any of the scenarios below are detected, `cargo fix` will insert a "dum
127120

128121
以下のような状況を検知すると、`cargo fix` は "ダミーの let" をクロージャの中に挿入して、強制的に全ての変数がキャプチャされるようにします:
129122

130-
<!--
131123
```rust
132124
let x = (vec![22], vec![23]);
133125
let c = move || {
134126
// "Dummy let" that forces `x` to be captured in its entirety
135-
let _ = &x;
136-
137-
// Otherwise, only `x.0` would be captured here
138-
println!("{:?}", x.0);
139-
};
140-
```
141-
-->
142-
143-
```rust
144-
let x = (vec![22], vec![23]);
145-
let c = move || {
146127
// `x` 全体が強制的にキャプチャされるための "ダミーの let"
147128
let _ = &x;
148129

130+
// Otherwise, only `x.0` would be captured here
149131
// それがないと、`x.0` だけがここでキャプチャされる
150132
println!("{:?}", x.0);
151133
};
@@ -169,23 +151,11 @@ Closures now only capture data that needs to be read, which means the following
169151

170152
クロージャは本当に読む必要のあるデータだけをキャプチャするようになったので、次のコードは `x` をキャプチャしません:
171153

172-
<!--
173154
```rust
174155
let x = 10;
175156
let c = || {
176157
let _ = x; // no-op
177-
};
178-
179-
let c = || match x {
180-
_ => println!("Hello World!")
181-
};
182-
```
183-
-->
184-
185-
```rust
186-
let x = 10;
187-
let c = || {
188-
let _ = x; // 何もしない
158+
// 何もしない
189159
};
190160

191161
let c = || match x {
@@ -223,7 +193,6 @@ When a closure takes ownership of a value from a variable `t`, that value is the
223193

224194
クロージャが変数 `t` の所有権を取るとき、`t` がドロップされるのは `t` がスコープ外に出たときではなく、そのクロージャがドロップされたときになります:
225195

226-
<!--
227196
```rust
228197
# fn move_value<T>(_: T){}
229198
{
@@ -232,19 +201,9 @@ When a closure takes ownership of a value from a variable `t`, that value is the
232201
{
233202
let c = || move_value(t); // t is moved here
234203
} // c is dropped, which drops the tuple `t` as well
204+
// c がドロップされ、そのときにタプル `t` もまたドロップされる
235205
} // t goes out of scope here
236-
```
237-
-->
238-
239-
```rust
240-
# fn move_value<T>(_: T){}
241-
{
242-
let t = (vec![0], vec![0]);
243-
244-
{
245-
let c = || move_value(t); // t はここでムーブされる
246-
} // c がドロップされ、そのときにタプル `t` もまたドロップされる
247-
} // t はここでスコープを抜ける
206+
// t はここでスコープを抜ける
248207
```
249208

250209
<!--
@@ -253,7 +212,6 @@ The above code will run the same in both Rust 2018 and Rust 2021. However, in ca
253212

254213
上記のコードの挙動は Rust 2018 と Rust 2021 で同じです。ところが、クロージャが変数の<!-- -->_一部_<!-- -->の所有権を取るとき、違いが発生します:
255214

256-
<!--
257215
```rust
258216
# fn move_value<T>(_: T){}
259217
{
@@ -263,46 +221,28 @@ The above code will run the same in both Rust 2018 and Rust 2021. However, in ca
263221
let c = || {
264222
// In Rust 2018, captures all of `t`.
265223
// In Rust 2021, captures only `t.0`
224+
// Rust 2018 では、`t` 全体がキャプチャされる。
225+
// Rust 2018 では、`t.0` だけがキャプチャされる
266226
move_value(t.0);
267227
};
268228

269229
// In Rust 2018, `c` (and `t`) are both dropped when we
270230
// exit this block.
231+
// Rust 2018 では、 `c` (と `t`) の両方が
232+
// このブロックを抜けるときにドロップされる。
271233
//
272234
// In Rust 2021, `c` and `t.0` are both dropped when we
273235
// exit this block.
236+
// Rust 2021 では、 `c` と `t.0` の両方が
237+
// このブロックを抜けるときにドロップされる。
274238
}
275239

276240
// In Rust 2018, the value from `t` has been moved and is
277241
// not dropped.
242+
// Rust 2018 では、`t` はすでにムーブされており、ここではドロップされない
278243
//
279244
// In Rust 2021, the value from `t.0` has been moved, but `t.1`
280245
// remains, so it will be dropped here.
281-
}
282-
```
283-
-->
284-
285-
```rust
286-
# fn move_value<T>(_: T){}
287-
{
288-
let t = (vec![0], vec![0]);
289-
290-
{
291-
let c = || {
292-
// Rust 2018 では、`t` 全体がキャプチャされる。
293-
// Rust 2018 では、`t.0` だけがキャプチャされる
294-
move_value(t.0);
295-
};
296-
297-
// Rust 2018 では、 `c` (と `t`) の両方が
298-
// このブロックを抜けるときにドロップされる。
299-
//
300-
// Rust 2021 では、 `c` と `t.0` の両方が
301-
// このブロックを抜けるときにドロップされる。
302-
}
303-
304-
// Rust 2018 では、`t` はすでにムーブされており、ここではドロップされない
305-
//
306246
// Rust 2021 では、`t.0` はムーブされているが、
307247
// `t.1` は残っており、ここでドロップされる
308248
}
@@ -372,7 +312,6 @@ With disjoint captures, only the specific field mentioned in the closure gets ca
372312

373313
フィールドごとのキャプチャが導入されると、キャプチャ内で使用されているフィールドだけがキャプチャされますが、フィールドの中身はもともと `Send`/`Sync` でなかったのですから、せっかくラッパーを作っても元の木阿弥です。
374314

375-
<!--
376315
```rust
377316
use std::thread;
378317

@@ -388,22 +327,5 @@ let c = thread::spawn(move || {
388327
*(px.0) += 10;
389328
}
390329
}); // Closure captured px.0 which is not Send
391-
```
392-
-->
393-
394-
```rust
395-
use std::thread;
396-
397-
struct Ptr(*mut i32);
398-
unsafe impl Send for Ptr {}
399-
400-
401-
let mut x = 5;
402-
let px = Ptr(&mut x as *mut i32);
403-
404-
let c = thread::spawn(move || {
405-
unsafe {
406-
*(px.0) += 10;
407-
}
408-
}); // クロージャは px.0 をキャプチャしたが、これは Send ではない
330+
// クロージャは px.0 をキャプチャしたが、これは Send ではない
409331
```

0 commit comments

Comments
 (0)