Skip to content

Commit 9dba7d1

Browse files
author
Document updater
committed
Merge remote-tracking branch 'origin/master'
2 parents a416a50 + c466c32 commit 9dba7d1

File tree

2 files changed

+108
-6
lines changed

2 files changed

+108
-6
lines changed

src/SUMMARY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
* [チェックされないメモリ](unchecked-uninit.md)
3232
* [所有権に基づいたリソース管理](obrm.md)
3333
* [コンストラクタ](constructors.md)
34-
* [Destructors](destructors.md)
34+
* [デストラクタ](destructors.md)
3535
* [リーク](leaking.md)
3636
* [巻き戻し](unwinding.md)
3737
* [例外安全性](exception-safety.md)

src/destructors.md

Lines changed: 107 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,67 @@
1+
<!--
12
# Destructors
3+
-->
24

5+
# デストラクタ
6+
7+
<!--
38
What the language *does* provide is full-blown automatic destructors through the
49
`Drop` trait, which provides the following method:
10+
-->
11+
12+
言語が*実際に*提供しているものは、 `Drop` トレイトを通じた完全に自動的な
13+
デストラクタで、以下のメソッドを提供しています。
514

615
```rust,ignore
716
fn drop(&mut self);
817
```
918

19+
<!--
1020
This method gives the type time to somehow finish what it was doing.
21+
-->
22+
23+
このメソッドは、型が行なっていたことをなんとか終わらせるための時間を、型に
24+
与えます。
1125

26+
<!--
1227
**After `drop` is run, Rust will recursively try to drop all of the fields
1328
of `self`.**
29+
-->
1430

31+
**`drop` が実行された後、 Rust は `self` の全てのフィールドのドロップを再帰的に実行しようとします。**
32+
33+
<!--
1534
This is a convenience feature so that you don't have to write "destructor
1635
boilerplate" to drop children. If a struct has no special logic for being
1736
dropped other than dropping its children, then it means `Drop` doesn't need to
1837
be implemented at all!
38+
-->
39+
40+
これは便利な機能で、子フィールドをドロップするための "デストラクタの決まり文句" を
41+
書く必要がありません。もし構造体に、子フィールドをドロップする以外の、ドロップされる際の
42+
特別なロジックが存在しなければ、 `Drop` を実装する必要が全くありません!
1943

44+
<!--
2045
**There is no stable way to prevent this behavior in Rust 1.0.**
46+
-->
2147

48+
**この振る舞いを防ぐステーブルな方法は、 Rust 1.0 の時点で存在しません**
49+
50+
<!--
2251
Note that taking `&mut self` means that even if you could suppress recursive
2352
Drop, Rust will prevent you from e.g. moving fields out of self. For most types,
2453
this is totally fine.
54+
-->
55+
56+
`&mut self` を受け取ることは、再帰ドロップを防ぐことが出来たとしても、例えば self から
57+
フィールドをムーブすることが妨げられることに注意してください。
58+
ほとんどの型にとっては、全く問題ありません。
2559

60+
<!--
2661
For instance, a custom implementation of `Box` might write `Drop` like this:
62+
-->
63+
64+
例えば `Box` のカスタム実装では、以下のような `Drop` を書くかもしれません。
2765

2866
```rust
2967
#![feature(alloc, heap_api, unique)]
@@ -50,11 +88,22 @@ impl<T> Drop for Box<T> {
5088
# fn main() {}
5189
```
5290

91+
<!--
5392
and this works fine because when Rust goes to drop the `ptr` field it just sees
5493
a [Unique] that has no actual `Drop` implementation. Similarly nothing can
5594
use-after-free the `ptr` because when drop exits, it becomes inaccessible.
95+
-->
5696

97+
そしてこれは、 Rust が `ptr` フィールドをドロップする際、単に、実際の `Drop` 実装が
98+
ない [Unique] に着目するため、このコードは問題なく動くのです。
99+
同様に、解放後は `ptr` を使用することが出来ません。なぜならドロップが存在する場合、
100+
そのドロップ実装にアクセス不可能となるからです。
101+
102+
<!--
57103
However this wouldn't work:
104+
-->
105+
106+
しかし、このコードは動かないでしょう。
58107

59108
```rust
60109
#![feature(alloc, heap_api, unique)]
@@ -84,8 +133,8 @@ struct SuperBox<T> { my_box: Box<T> }
84133
impl<T> Drop for SuperBox<T> {
85134
fn drop(&mut self) {
86135
unsafe {
87-
// Hyper-optimized: deallocate the box's contents for it
88-
// without `drop`ing the contents
136+
// 超最適化: Box の内容を `drop` せずに
137+
// 内容をデアロケートします
89138
heap::deallocate((*self.my_box.ptr) as *mut u8,
90139
mem::size_of::<T>(),
91140
mem::align_of::<T>());
@@ -95,12 +144,23 @@ impl<T> Drop for SuperBox<T> {
95144
# fn main() {}
96145
```
97146

147+
<!--
98148
After we deallocate the `box`'s ptr in SuperBox's destructor, Rust will
99149
happily proceed to tell the box to Drop itself and everything will blow up with
100150
use-after-frees and double-frees.
151+
-->
101152

153+
SuperBox のデストラクタで `box` の ptr をデアロケートした後、 Rust は適切に box に、
154+
自身をドロップするよう通達し、その結果、解放後の使用や二重解放によって全部消し飛びます。
155+
156+
<!--
102157
Note that the recursive drop behavior applies to all structs and enums
103158
regardless of whether they implement Drop. Therefore something like
159+
-->
160+
161+
再帰ドロップは、構造体や列挙型が Drop を定義しているかしていないかによらず、
162+
全ての構造体や列挙型に適用されることに注意してください。
163+
ですから、以下のような
104164

105165
```rust
106166
struct Boxy<T> {
@@ -110,11 +170,21 @@ struct Boxy<T> {
110170
}
111171
```
112172

173+
<!--
113174
will have its data1 and data2's fields destructors whenever it "would" be
114175
dropped, even though it itself doesn't implement Drop. We say that such a type
115176
*needs Drop*, even though it is not itself Drop.
177+
-->
178+
179+
ものは、それ自体が Drop を実装していなくても、それがドロップ*される*ときには毎回、 data1 と data2 の
180+
フィールドをデストラクトします。これを、そのような型が *Drop を必要とする*と言います。型が Drop を
181+
実装していなくてもです。
116182

183+
<!--
117184
Similarly,
185+
-->
186+
187+
同様に
118188

119189
```rust
120190
enum Link {
@@ -123,16 +193,32 @@ enum Link {
123193
}
124194
```
125195

196+
<!--
126197
will have its inner Box field dropped if and only if an instance stores the
127198
Next variant.
199+
-->
200+
201+
これは、インスタンスが Next を格納しているとき、そのときだけ内部の Box フィールドを
202+
ドロップします。
128203

204+
<!--
129205
In general this works really nicely because you don't need to worry about
130206
adding/removing drops when you refactor your data layout. Still there's
131207
certainly many valid usecases for needing to do trickier things with
132208
destructors.
209+
-->
133210

211+
一般に、これは非常に上手く動きます。なぜなら、データレイアウトをリファクタリングするときに、
212+
ドロップを追加あるいは削除する心配が必要ないからです。もちろん、デストラクタで何か
213+
トリッキーなことが必要になる妥当なケースは、たくさんあります。
214+
215+
<!--
134216
The classic safe solution to overriding recursive drop and allowing moving out
135217
of Self during `drop` is to use an Option:
218+
-->
219+
220+
再帰ドロップを上書きし、 `drop` の最中に Self からのムーブを可能にする、
221+
古典的で安全な解決策は、 Option を使うことです。
136222

137223
```rust
138224
#![feature(alloc, heap_api, unique)]
@@ -162,9 +248,10 @@ struct SuperBox<T> { my_box: Option<Box<T>> }
162248
impl<T> Drop for SuperBox<T> {
163249
fn drop(&mut self) {
164250
unsafe {
165-
// Hyper-optimized: deallocate the box's contents for it
166-
// without `drop`ing the contents. Need to set the `box`
167-
// field as `None` to prevent Rust from trying to Drop it.
251+
// 超最適化: Box の内容を `drop` せずに
252+
// 内容をデアロケートします
253+
// Rust が `box` フィールドをドロップしようとさせないために、
254+
// `box` フィールドを `None` と設定する必要があります
168255
let my_box = self.my_box.take().unwrap();
169256
heap::deallocate((*my_box.ptr) as *mut u8,
170257
mem::size_of::<T>(),
@@ -176,15 +263,30 @@ impl<T> Drop for SuperBox<T> {
176263
# fn main() {}
177264
```
178265

266+
<!--
179267
However this has fairly odd semantics: you're saying that a field that *should*
180268
always be Some *may* be None, just because that happens in the destructor. Of
181269
course this conversely makes a lot of sense: you can call arbitrary methods on
182270
self during the destructor, and this should prevent you from ever doing so after
183271
deinitializing the field. Not that it will prevent you from producing any other
184272
arbitrarily invalid state in there.
273+
-->
185274

275+
しかしながら、これはかなり奇妙なセマンティクスです。すなわち、常に Some である*べき*
276+
フィールドが、 None に*なりうる*と言っているからです。なぜならこれが、
277+
デストラクタで起こっているからです。勿論、これは逆に大いに納得がいきます。
278+
デストラクタ内で self に対して任意のメソッドを呼ぶことができ、同じことが、
279+
フィールドが未初期化状態に戻されたあとに行われるのを防ぐはずですから。
280+
だからといって、他の不正状態が生まれることを防ぐわけではありませんが。
281+
282+
<!--
186283
On balance this is an ok choice. Certainly what you should reach for by default.
187284
However, in the future we expect there to be a first-class way to announce that
188285
a field shouldn't be automatically dropped.
286+
-->
287+
288+
結局のところ、これはそれほど悪くないやり方です。明らかに誰もが必要とする機能です。
289+
しかしながら将来、あるフィールドが自動的にドロップされるべきでないと知らせる、
290+
素晴らしい方法が現れると我々は期待しています。
189291

190292
[Unique]: phantom-data.html

0 commit comments

Comments
 (0)