1
1
% 型間のキャスト
2
2
<!-- % Casting Between Types -->
3
3
4
- Rust, with its focus on safety, provides two different ways of casting
4
+ <!-- Rust, with its focus on safety, provides two different ways of casting
5
5
different types between each other. The first, `as`, is for safe casts.
6
6
In contrast, `transmute` allows for arbitrary casting, and is one of the
7
- most dangerous features of Rust!
7
+ most dangerous features of Rust! -->
8
+ Rustは安全性に焦点を合わせており、異なる型の間を互いにキャストするために二つの異なる方法を提供しています。
9
+ 一つは ` as ` であり、これは安全なキャストに使われます。
10
+ 逆に ` transmute ` は任意のキャストに使え、Rustにおける最も危険なフィーチャの一つです!
8
11
9
- # Coercion
12
+ <!-- # Coercion -->
13
+ # 型強制
10
14
11
- Coercion between types is implicit and has no syntax of its own, but can
12
- be spelled out with [ ` as ` ] ( #explicit-coercions ) .
15
+ <!-- Coercion between types is implicit and has no syntax of its own, but can
16
+ be spelled out with [`as`](#explicit-coercions). -->
17
+ 型強制は暗黙に行われ、それ自体に構文はありませんが、[ ` as ` ] ( #明示的型強制 ) で書くこともできます。
13
18
14
- Coercion occurs in ` let ` , ` const ` , and ` static ` statements; in
19
+ <!-- Coercion occurs in `let`, `const`, and `static` statements; in
15
20
function call arguments; in field values in struct initialization; and in a
16
- function result.
21
+ function result. -->
22
+ 型強制が現れるのは、 ` let ` ・ ` const ` ・ ` static ` 文、関数呼び出しの引数、構造体初期化の際のフィールド値、そして関数の結果です。
17
23
18
- The most common case of coercion is removing mutability from a reference:
24
+ <!-- The most common case of coercion is removing mutability from a reference: -->
25
+ 一番よくある型強制は、参照からミュータビリティを取り除くものです。
19
26
20
- * ` &mut T ` to ` &T `
21
-
22
- An analogous conversion is to remove mutability from a
23
- [ raw pointer] ( raw-pointers.md ) :
27
+ <!-- * `&mut T` to `&T` -->
28
+ * ` &mut T ` から ` &T ` へ
24
29
25
- * ` *mut T ` to ` *const T `
26
-
27
- References can also be coerced to raw pointers:
30
+ <!-- An analogous conversion is to remove mutability from a
31
+ [raw pointer](raw-pointers.md): -->
32
+ 似たような変換としては、 [ 生ポインタ ] ( raw- pointers.md ) からミュータビリティを取り除くものがあります。
28
33
29
- * ` &T ` to ` *const T `
34
+ <!-- * `*mut T` to `*const T` -->
35
+ * ` *mut T ` から ` *const T ` へ
30
36
31
- * ` &mut T ` to ` *mut T `
37
+ <!-- References can also be coerced to raw pointers: -->
38
+ 参照も同様に、生ポインタへ型強制できます。
32
39
33
- Custom coercions may be defined using [ ` Deref ` ] ( deref-coercions.md ) .
40
+ <!-- * `&T` to `*const T` -->
41
+ * ` &T ` から ` *const T ` へ
34
42
35
- Coercion is transitive.
36
-
43
+ <!-- * `&mut T` to `*mut T` -->
44
+ * ` &mut T ` から ` *mut T ` へ
45
+
46
+ <!-- Custom coercions may be defined using [`Deref`](deref-coercions.md). -->
47
+ [ ` Deref ` ] ( deref-coercions.md ) によって、カスタマイズされた型強制が定義されることもあります。
48
+
49
+ <!-- Coercion is transitive. -->
50
+ 型強制は推移的です。
51
+
52
+ <!-- # `as` -->
37
53
# ` as `
38
54
39
- The ` as ` keyword does safe casting:
55
+ <!-- The `as` keyword does safe casting: -->
56
+ ` as ` というキーワードは安全なキャストを行います。
40
57
41
58
``` rust
42
59
let x : i32 = 5 ;
43
60
44
61
let y = x as i64 ;
45
62
```
46
63
47
- There are three major categories of safe cast: explicit coercions, casts
48
- between numeric types, and pointer casts.
64
+ <!-- There are three major categories of safe cast: explicit coercions, casts
65
+ between numeric types, and pointer casts. -->
66
+ 安全なキャストは大きく三つに分類されます。
67
+ 明示的型強制、数値型間のキャスト、そして、ポインタキャストです。
49
68
50
- Casting is not transitive: even if ` e as U1 as U2 ` is a valid
69
+ <!-- Casting is not transitive: even if `e as U1 as U2` is a valid
51
70
expression, `e as U2` is not necessarily so (in fact it will only be valid if
52
- ` U1 ` coerces to ` U2 ` ).
71
+ `U1` coerces to `U2`). -->
72
+ キャストは推移的ではありません。
73
+ ` e as U1 as U2 ` が正しい式であったとしても、 ` e as U2 ` が必ずしも正しいとは限らないのです。
74
+ (実際、この式が正しくなるのは、 ` U1 ` が ` U2 ` へ型強制されるときのみです。)
53
75
54
76
55
- ## Explicit coercions
77
+ <!-- ## Explicit coercions -->
78
+ ## 明示的型強制
56
79
57
- A cast ` e as U ` is valid if ` e ` has type ` T ` and ` T ` * coerces* to ` U ` .
80
+ <!-- A cast `e as U` is valid if `e` has type `T` and `T` *coerces* to `U`. -->
81
+ ` e as U ` というキャストは、 ` e ` が型 ` T ` を持ち、かつ ` T ` が ` U ` に型強制されるとき、有効です。
58
82
59
- ## Numeric casts
83
+ <!-- ## Numeric casts -->
84
+ ## 数値キャスト
60
85
61
- A cast ` e as U ` is also valid in any of the following cases:
86
+ <!-- A cast `e as U` is also valid in any of the following cases: -->
87
+ ` e as U ` というキャストは、以下のような場合も有効です。
62
88
63
- * ` e ` has type ` T ` and ` T ` and ` U ` are any numeric types; * numeric-cast*
64
- * ` e ` is a C-like enum (with no data attached to the variants),
65
- and ` U ` is an integer type; * enum-cast*
66
- * ` e ` has type ` bool ` or ` char ` and ` U ` is an integer type; * prim-int-cast*
67
- * ` e ` has type ` u8 ` and ` U ` is ` char ` ; * u8-char-cast*
68
-
69
- For example
89
+ <!-- * `e` has type `T` and `T` and `U` are any numeric types; *numeric-cast* -->
90
+ <!-- * `e` is a C-like enum (with no data attached to the variants),
91
+ and `U` is an integer type; *enum-cast* -->
92
+ <!-- * `e` has type `bool` or `char` and `U` is an integer type; *prim-int-cast* -->
93
+ <!-- * `e` has type `u8` and `U` is `char`; *u8-char-cast* -->
94
+ * ` e ` が型 ` T ` を持ち、 ` T ` と ` U ` が数値型であるとき; * numeric-cast*
95
+ * ` e ` が C-likeな列挙型であり(つまり、ヴァリアントがデータを持っておらず)、 ` U ` が整数型であるとき; * enum-cast*
96
+ * ` e ` の型が ` bool ` か ` char ` であり、 ` U ` が整数型であるとき; * prim-int-cast*
97
+ * ` e ` が型 ` u8 ` を持ち、 ` U ` が ` char ` であるとき; * u8-char-cast*
98
+
99
+ <!-- For example -->
100
+ 例えば、
70
101
71
102
``` rust
72
103
let one = true as u8 ;
73
104
let at_sign = 64 as char ;
74
105
let two_hundred = - 56i8 as u8 ;
75
106
```
76
107
77
- The semantics of numeric casts are:
78
-
79
- * Casting between two integers of the same size (e.g. i32 -> u32) is a no-op
80
- * Casting from a larger integer to a smaller integer (e.g. u32 -> u8) will
81
- truncate
82
- * Casting from a smaller integer to a larger integer (e.g. u8 -> u32) will
83
- * zero-extend if the source is unsigned
84
- * sign-extend if the source is signed
85
- * Casting from a float to an integer will round the float towards zero
86
- * ** [ NOTE: currently this will cause Undefined Behavior if the rounded
87
- value cannot be represented by the target integer type] [ float-int ] ** .
88
- This includes Inf and NaN. This is a bug and will be fixed.
89
- * Casting from an integer to float will produce the floating point
90
- representation of the integer, rounded if necessary (rounding strategy
91
- unspecified)
92
- * Casting from an f32 to an f64 is perfect and lossless
93
- * Casting from an f64 to an f32 will produce the closest possible value
94
- (rounding strategy unspecified)
95
- * ** [ NOTE: currently this will cause Undefined Behavior if the value
96
- is finite but larger or smaller than the largest or smallest finite
97
- value representable by f32] [ float-float ] ** . This is a bug and will
98
- be fixed.
108
+ <!-- The semantics of numeric casts are: -->
109
+ 数値キャストのセマンティクスは以下の通りです。
110
+
111
+ <!-- * Casting between two integers of the same size (e.g. i32 -> u32) is a no-op -->
112
+ <!-- * Casting from a larger integer to a smaller integer (e.g. u32 -> u8) will -->
113
+ <!-- truncate -->
114
+ <!-- * Casting from a smaller integer to a larger integer (e.g. u8 -> u32) will -->
115
+ <!-- * zero-extend if the source is unsigned -->
116
+ <!-- * sign-extend if the source is signed -->
117
+ <!-- * Casting from a float to an integer will round the float towards zero -->
118
+ <!-- * **[NOTE: currently this will cause Undefined Behavior if the rounded -->
119
+ <!-- value cannot be represented by the target integer type][float-int]**. -->
120
+ <!-- This includes Inf and NaN. This is a bug and will be fixed. -->
121
+ <!-- * Casting from an integer to float will produce the floating point -->
122
+ <!-- representation of the integer, rounded if necessary (rounding strategy -->
123
+ <!-- unspecified) -->
124
+ <!-- * Casting from an f32 to an f64 is perfect and lossless -->
125
+ <!-- * Casting from an f64 to an f32 will produce the closest possible value -->
126
+ <!-- (rounding strategy unspecified) -->
127
+ <!-- * **[NOTE: currently this will cause Undefined Behavior if the value -->
128
+ <!-- is finite but larger or smaller than the largest or smallest finite -->
129
+ <!-- value representable by f32][float-float]**. This is a bug and will -->
130
+ <!-- be fixed. -->
131
+
132
+ * サイズの同じ二つの整数間のキャスト (例えば、i32 -> u32) は何も行いません
133
+ * サイズの大きい整数から小さい整数へのキャスト (例えば、u32 -> u8) では切り捨てを行います
134
+ * サイズの小さい整数から大きい整数へのキャスト (例えば、u8 -> u32) では、
135
+ * 元の整数が符号無しならば、ゼロ拡張を行います
136
+ * 元の整数が符号付きならば、符号拡張を行います
137
+ * 浮動小数点数から整数へのキャストでは、0方向への丸めを行います
138
+ * ** [ 注意: 現在、丸められた値がキャスト先の整数型で扱えない場合、このキャストは未定義動作を引き起こします。] [ float-int ] **
139
+ これには Inf や NaN も含まれます。
140
+ これはバグであり、修正される予定です。
141
+ * 整数から浮動小数点数へのキャストでは、必要に応じて丸めが行われて、その整数を表す浮動小数点数がつくられます
142
+ (丸め戦略は指定されていません)
143
+ * f32 から f64 へのキャストは完全で精度は落ちません
144
+ * f64 から f32 へのキャストでは、表現できる最も近い値がつくられます
145
+ (丸め戦略は指定されていません)
146
+ * ** [ 注意: 現在、値が有限でありながらf32 で表現できる最大(最小)の有限値より大きい(小さい)場合、このキャストは未定義動作を引き起こします。] [ float-float ] **
147
+ これはバグであり、修正される予定です。
99
148
100
149
[ float-int ] : https://github.com/rust-lang/rust/issues/10184
101
150
[ float-float ] : https://github.com/rust-lang/rust/issues/15536
102
-
103
- ## Pointer casts
104
-
105
- Perhaps surprisingly, it is safe to cast [ raw pointers] ( raw-pointers.md ) to and
151
+
152
+ <!-- ## Pointer casts -->
153
+ ## ポインタキャスト
154
+
155
+ <!-- Perhaps surprisingly, it is safe to cast [raw pointers](raw-pointers.md) to and
106
156
from integers, and to cast between pointers to different types subject to
107
- some constraints. It is only unsafe to dereference the pointer:
157
+ some constraints. It is only unsafe to dereference the pointer: -->
158
+ 驚くかもしれませんが、いくつかの制約のもとで、 [ 生ポインタ] ( raw-pointers.md ) と整数の間のキャストや、ポインタと他の型の間のキャストは安全です。
159
+ 安全でないのはポインタの参照外しだけなのです。
108
160
109
161
``` rust
110
- let a = 300 as * const char ; // a pointer to location 300
162
+ # // let a = 300 as *const char; // a pointer to location 300
163
+ let a = 300 as * const char ; // 300番地へのポインタ
111
164
let b = a as u32 ;
112
165
```
113
166
114
- ` e as U ` is a valid pointer cast in any of the following cases:
167
+ <!-- `e as U` is a valid pointer cast in any of the following cases: -->
168
+ ` e as U ` が正しいポインタキャストであるのは、以下の場合です。
115
169
116
- * ` e ` has type ` *T ` , ` U ` has type ` *U_0 ` , and either ` U_0: Sized ` or
117
- ` unsize_kind(T) == unsize_kind(U_0) ` ; a * ptr-ptr-cast*
118
-
119
- * ` e ` has type ` *T ` and ` U ` is a numeric type, while ` T: Sized ` ; * ptr-addr-cast*
170
+ <!-- * `e` has type `*T`, `U` has type `*U_0`, and either `U_0: Sized` or
171
+ `unsize_kind(T) == unsize_kind(U_0)`; a *ptr-ptr-cast* -->
172
+ * ` e ` が型 ` *T ` を持ち、 ` U ` が ` *U_0 ` であり、 ` U_0: Sized ` または ` unsize_kind(T) == unsize_kind(U_0) ` である場合; * ptr-ptr-cast*
120
173
121
- * ` e ` is an integer and ` U ` is ` *U_0 ` , while ` U_0: Sized ` ; * addr-ptr-cast*
174
+ <!-- * `e` has type `*T` and `U` is a numeric type, while `T: Sized`; *ptr-addr-cast* -->
175
+ * ` e ` が型 ` *T ` を持ち、 ` U ` が数値型で、 ` T: Sized ` である場合; * ptr-addr-cast*
122
176
123
- * ` e ` has type ` &[T; n] ` and ` U ` is ` *const T ` ; * array-ptr-cast*
177
+ <!-- * `e` is an integer and `U` is `*U_0`, while `U_0: Sized`; *addr-ptr-cast* -->
178
+ * ` e ` が整数、` U ` が ` *U_0 ` であり、 ` U_0: Sized ` である場合; * addr-ptr-cast*
124
179
125
- * ` e ` is a function pointer type and ` U ` has type ` *T ` ,
126
- while ` T: Sized ` ; * fptr -ptr-cast*
180
+ <!-- * `e` has type `&[T; n]` and `U` is `*const T`; *array-ptr-cast* -->
181
+ * ` e ` が型 ` &[T; n] ` を持ち、 ` U ` が ` *const T ` である場合 ; * array -ptr-cast*
127
182
128
- * ` e ` is a function pointer type and ` U ` is an integer; * fptr-addr-cast*
183
+ <!-- * `e` is a function pointer type and `U` has type `*T`,
184
+ while `T: Sized`; *fptr-ptr-cast* -->
185
+ * ` e ` が関数ポインタ型であり、 ` U ` が ` *T ` であって、` T: Sized ` の場合; * fptr-ptr-cast*
129
186
187
+ <!-- * `e` is a function pointer type and `U` is an integer; *fptr-addr-cast* -->
188
+ * ` e ` が関数ポインタ型であり、 ` U ` が整数である場合; * fptr-addr-cast*
130
189
131
190
# ` transmute `
132
191
133
- ` as ` only allows safe casting, and will for example reject an attempt to
134
- cast four bytes into a ` u32 ` :
192
+ <!-- `as` only allows safe casting, and will for example reject an attempt to
193
+ cast four bytes into a `u32`: -->
194
+ ` as ` は安全なキャストしか許さず、例えば4つのバイト値を ` u32 ` へキャストすることはできません。
135
195
136
196
``` rust,ignore
137
197
let a = [0u8, 0u8, 0u8, 0u8];
138
198
139
- let b = a as u32; // four eights makes 32
199
+ # // let b = a as u32; // four eights makes 32
200
+ let b = a as u32; // 4つの8で32になる
140
201
```
141
202
142
- This errors with:
203
+ <!-- This errors with: -->
204
+ これは以下のようなメッセージがでて、エラーになります。
143
205
144
- ``` text
206
+ <!-- ```text
145
207
error: non-scalar cast: `[u8; 4]` as `u32`
146
208
let b = a as u32; // four eights makes 32
147
209
^~~~~~~~
210
+ ``` -->
211
+ ``` text
212
+ error: non-scalar cast: `[u8; 4]` as `u32`
213
+ let b = a as u32; // 4つの8で32になる
214
+ ^~~~~~~~
148
215
```
149
216
150
- This is a ‘non-scalar cast’ because we have multiple values here: the four
217
+ <!-- This is a ‘non-scalar cast’ because we have multiple values here: the four
151
218
elements of the array. These kinds of casts are very dangerous, because they
152
219
make assumptions about the way that multiple underlying structures are
153
- implemented. For this, we need something more dangerous.
220
+ implemented. For this, we need something more dangerous. -->
221
+ これは「non-scalar cast」であり、複数の値、つまり配列の4つの要素、があることが原因です。
222
+ この種類のキャストはとても危険です。
223
+ なぜなら、複数の裏に隠れた構造がどう実装されているかについて仮定をおいているからです。
224
+ そのためもっと危険なものが必要になります。
154
225
155
- The ` transmute ` function is provided by a [ compiler intrinsic] [ intrinsics ] , and
226
+ <!-- The `transmute` function is provided by a [compiler intrinsic][intrinsics], and
156
227
what it does is very simple, but very scary. It tells Rust to treat a value of
157
228
one type as though it were another type. It does this regardless of the
158
- typechecking system, and just completely trusts you.
229
+ typechecking system, and just completely trusts you. -->
230
+ ` transmute ` 関数は [ コンパイラ intrinsic] [ intrinsics ] によって提供されており、やることはとてもシンプルながら、とても恐ろしいです。
231
+ この関数は、Rustに対し、ある型の値を他の型であるかのように扱うように伝えます。
232
+ これは型検査システムに関係なく行われ、完全に使用者頼みです。
159
233
160
234
[ intrinsics ] : intrinsics.html
161
235
162
- In our previous example, we know that an array of four ` u8 ` s represents a ` u32 `
236
+ <!-- In our previous example, we know that an array of four `u8`s represents a `u32`
163
237
properly, and so we want to do the cast. Using `transmute` instead of `as`,
164
- Rust lets us:
238
+ Rust lets us: -->
239
+ 前の例では、4つの ` u8 ` からなる配列が ちゃんと ` u32 ` を表していることを知った上で、キャストを行おうとしました。
240
+ これは、` as ` の代わりに ` transmute ` を使うことで、次のように書けます。
165
241
166
242
``` rust
167
243
use std :: mem;
@@ -173,15 +249,22 @@ unsafe {
173
249
}
174
250
```
175
251
176
- We have to wrap the operation in an ` unsafe ` block for this to compile
252
+ <!-- We have to wrap the operation in an `unsafe` block for this to compile
177
253
successfully. Technically, only the `mem::transmute` call itself needs to be in
178
254
the block, but it's nice in this case to enclose everything related, so you
179
255
know where to look. In this case, the details about `a` are also important, and
180
256
so they're in the block. You'll see code in either style, sometimes the context
181
- is too far away, and wrapping all of the code in ` unsafe ` isn't a great idea.
182
-
183
- While ` transmute ` does very little checking, it will at least make sure that
184
- the types are the same size. This errors:
257
+ is too far away, and wrapping all of the code in `unsafe` isn't a great idea. -->
258
+ コンパイルを成功させるために、この操作は ` unsafe ` ブロックでくるんであります。
259
+ 技術的には、 ` mem::transmute ` の呼び出しのみをブロックに入れればいいのですが、今回はどこを見ればよいかわかるよう、関連するもの全部を囲んでいます。
260
+ この例では ` a ` に関する詳細も重要であるため、ブロックにいれてあります。
261
+ ただ、文脈が離れすぎているときは、こう書かないこともあるでしょう。
262
+ そういうときは、コード全体を ` unsafe ` でくるむことは良い考えではないのです。
263
+
264
+ <!-- While `transmute` does very little checking, it will at least make sure that
265
+ the types are the same size. This errors: -->
266
+ ` transmute ` はほとんどチェックを行わないのですが、最低限、型同士が同じサイズかの確認はします。
267
+ そのため、次の例はエラーになります。
185
268
186
269
``` rust,ignore
187
270
use std::mem;
@@ -193,11 +276,13 @@ unsafe {
193
276
}
194
277
```
195
278
196
- with:
279
+ <!-- with: -->
280
+ エラーメッセージはこうです。
197
281
198
282
``` text
199
283
error: transmute called with differently sized types: [u8; 4] (32 bits) to u64
200
284
(64 bits)
201
285
```
202
286
203
- Other than that, you're on your own!
287
+ <!-- Other than that, you're on your own! -->
288
+ ただそれ以外に関しては、自己責任です!
0 commit comments