1
+ <!--
1
2
# Destructors
3
+ -->
2
4
5
+ # デストラクタ
6
+
7
+ <!--
3
8
What the language *does* provide is full-blown automatic destructors through the
4
9
`Drop` trait, which provides the following method:
10
+ -->
11
+
12
+ 言語が* 実際に* 提供しているものは、 ` Drop ` トレイトを通じた完全に自動的な
13
+ デストラクタで、以下のメソッドを提供しています。
5
14
6
15
``` rust,ignore
7
16
fn drop(&mut self);
8
17
```
9
18
19
+ <!--
10
20
This method gives the type time to somehow finish what it was doing.
21
+ -->
22
+
23
+ このメソッドは、型が行なっていたことをなんとか終わらせるための時間を、型に
24
+ 与えます。
11
25
26
+ <!--
12
27
**After `drop` is run, Rust will recursively try to drop all of the fields
13
28
of `self`.**
29
+ -->
14
30
31
+ ** ` drop ` が実行された後、 Rust は ` self ` の全てのフィールドのドロップを再帰的に実行しようとします。**
32
+
33
+ <!--
15
34
This is a convenience feature so that you don't have to write "destructor
16
35
boilerplate" to drop children. If a struct has no special logic for being
17
36
dropped other than dropping its children, then it means `Drop` doesn't need to
18
37
be implemented at all!
38
+ -->
39
+
40
+ これは便利な機能で、子フィールドをドロップするための "デストラクタの決まり文句" を
41
+ 書く必要がありません。もし構造体に、子フィールドをドロップする以外の、ドロップされる際の
42
+ 特別なロジックが存在しなければ、 ` Drop ` を実装する必要が全くありません!
19
43
44
+ <!--
20
45
**There is no stable way to prevent this behavior in Rust 1.0.**
46
+ -->
21
47
48
+ ** この振る舞いを防ぐステーブルな方法は、 Rust 1.0 の時点で存在しません**
49
+
50
+ <!--
22
51
Note that taking `&mut self` means that even if you could suppress recursive
23
52
Drop, Rust will prevent you from e.g. moving fields out of self. For most types,
24
53
this is totally fine.
54
+ -->
55
+
56
+ ` &mut self ` を受け取ることは、再帰ドロップを防ぐことが出来たとしても、例えば self から
57
+ フィールドをムーブすることが妨げられることに注意してください。
58
+ ほとんどの型にとっては、全く問題ありません。
25
59
60
+ <!--
26
61
For instance, a custom implementation of `Box` might write `Drop` like this:
62
+ -->
63
+
64
+ 例えば ` Box ` のカスタム実装では、以下のような ` Drop ` を書くかもしれません。
27
65
28
66
``` rust
29
67
#![feature(alloc, heap_api, unique)]
@@ -50,11 +88,22 @@ impl<T> Drop for Box<T> {
50
88
# fn main () {}
51
89
```
52
90
91
+ <!--
53
92
and this works fine because when Rust goes to drop the `ptr` field it just sees
54
93
a [Unique] that has no actual `Drop` implementation. Similarly nothing can
55
94
use-after-free the `ptr` because when drop exits, it becomes inaccessible.
95
+ -->
56
96
97
+ そしてこれは、 Rust が ` ptr ` フィールドをドロップする際、単に、実際の ` Drop ` 実装が
98
+ ない [ Unique] に着目するため、このコードは問題なく動くのです。
99
+ 同様に、解放後は ` ptr ` を使用することが出来ません。なぜならドロップが存在する場合、
100
+ そのドロップ実装にアクセス不可能となるからです。
101
+
102
+ <!--
57
103
However this wouldn't work:
104
+ -->
105
+
106
+ しかし、このコードは動かないでしょう。
58
107
59
108
``` rust
60
109
#![feature(alloc, heap_api, unique)]
@@ -84,8 +133,8 @@ struct SuperBox<T> { my_box: Box<T> }
84
133
impl <T > Drop for SuperBox <T > {
85
134
fn drop (& mut self ) {
86
135
unsafe {
87
- // Hyper-optimized: deallocate the box's contents for it
88
- // without `drop`ing the contents
136
+ // 超最適化: Box の内容を `drop` せずに
137
+ // 内容をデアロケートします
89
138
heap :: deallocate ((* self . my_box. ptr) as * mut u8 ,
90
139
mem :: size_of :: <T >(),
91
140
mem :: align_of :: <T >());
@@ -95,12 +144,23 @@ impl<T> Drop for SuperBox<T> {
95
144
# fn main () {}
96
145
```
97
146
147
+ <!--
98
148
After we deallocate the `box`'s ptr in SuperBox's destructor, Rust will
99
149
happily proceed to tell the box to Drop itself and everything will blow up with
100
150
use-after-frees and double-frees.
151
+ -->
101
152
153
+ SuperBox のデストラクタで ` box ` の ptr をデアロケートした後、 Rust は適切に box に、
154
+ 自身をドロップするよう通達し、その結果、解放後の使用や二重解放によって全部消し飛びます。
155
+
156
+ <!--
102
157
Note that the recursive drop behavior applies to all structs and enums
103
158
regardless of whether they implement Drop. Therefore something like
159
+ -->
160
+
161
+ 再帰ドロップは、構造体や列挙型が Drop を定義しているかしていないかによらず、
162
+ 全ての構造体や列挙型に適用されることに注意してください。
163
+ ですから、以下のような
104
164
105
165
``` rust
106
166
struct Boxy <T > {
@@ -110,11 +170,21 @@ struct Boxy<T> {
110
170
}
111
171
```
112
172
173
+ <!--
113
174
will have its data1 and data2's fields destructors whenever it "would" be
114
175
dropped, even though it itself doesn't implement Drop. We say that such a type
115
176
*needs Drop*, even though it is not itself Drop.
177
+ -->
178
+
179
+ ものは、それ自体が Drop を実装していなくても、それがドロップ* される* ときには毎回、 data1 と data2 の
180
+ フィールドをデストラクトします。これを、そのような型が * Drop を必要とする* と言います。型が Drop を
181
+ 実装していなくてもです。
116
182
183
+ <!--
117
184
Similarly,
185
+ -->
186
+
187
+ 同様に
118
188
119
189
``` rust
120
190
enum Link {
@@ -123,16 +193,32 @@ enum Link {
123
193
}
124
194
```
125
195
196
+ <!--
126
197
will have its inner Box field dropped if and only if an instance stores the
127
198
Next variant.
199
+ -->
200
+
201
+ これは、インスタンスが Next を格納しているとき、そのときだけ内部の Box フィールドを
202
+ ドロップします。
128
203
204
+ <!--
129
205
In general this works really nicely because you don't need to worry about
130
206
adding/removing drops when you refactor your data layout. Still there's
131
207
certainly many valid usecases for needing to do trickier things with
132
208
destructors.
209
+ -->
133
210
211
+ 一般に、これは非常に上手く動きます。なぜなら、データレイアウトをリファクタリングするときに、
212
+ ドロップを追加あるいは削除する心配が必要ないからです。もちろん、デストラクタで何か
213
+ トリッキーなことが必要になる妥当なケースは、たくさんあります。
214
+
215
+ <!--
134
216
The classic safe solution to overriding recursive drop and allowing moving out
135
217
of Self during `drop` is to use an Option:
218
+ -->
219
+
220
+ 再帰ドロップを上書きし、 ` drop ` の最中に Self からのムーブを可能にする、
221
+ 古典的で安全な解決策は、 Option を使うことです。
136
222
137
223
``` rust
138
224
#![feature(alloc, heap_api, unique)]
@@ -162,9 +248,10 @@ struct SuperBox<T> { my_box: Option<Box<T>> }
162
248
impl <T > Drop for SuperBox <T > {
163
249
fn drop (& mut self ) {
164
250
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` と設定する必要があります
168
255
let my_box = self . my_box. take (). unwrap ();
169
256
heap :: deallocate ((* my_box . ptr) as * mut u8 ,
170
257
mem :: size_of :: <T >(),
@@ -176,15 +263,30 @@ impl<T> Drop for SuperBox<T> {
176
263
# fn main () {}
177
264
```
178
265
266
+ <!--
179
267
However this has fairly odd semantics: you're saying that a field that *should*
180
268
always be Some *may* be None, just because that happens in the destructor. Of
181
269
course this conversely makes a lot of sense: you can call arbitrary methods on
182
270
self during the destructor, and this should prevent you from ever doing so after
183
271
deinitializing the field. Not that it will prevent you from producing any other
184
272
arbitrarily invalid state in there.
273
+ -->
185
274
275
+ しかしながら、これはかなり奇妙なセマンティクスです。すなわち、常に Some である* べき*
276
+ フィールドが、 None に* なりうる* と言っているからです。なぜならこれが、
277
+ デストラクタで起こっているからです。勿論、これは逆に大いに納得がいきます。
278
+ デストラクタ内で self に対して任意のメソッドを呼ぶことができ、同じことが、
279
+ フィールドが未初期化状態に戻されたあとに行われるのを防ぐはずですから。
280
+ だからといって、他の不正状態が生まれることを防ぐわけではありませんが。
281
+
282
+ <!--
186
283
On balance this is an ok choice. Certainly what you should reach for by default.
187
284
However, in the future we expect there to be a first-class way to announce that
188
285
a field shouldn't be automatically dropped.
286
+ -->
287
+
288
+ 結局のところ、これはそれほど悪くないやり方です。明らかに誰もが必要とする機能です。
289
+ しかしながら将来、あるフィールドが自動的にドロップされるべきでないと知らせる、
290
+ 素晴らしい方法が現れると我々は期待しています。
189
291
190
292
[ Unique ] : phantom-data.html
0 commit comments