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:
108
+ <!-- The semantics of numeric casts are: -->
109
+ 数値キャストのセマンティクスは以下の通りです。
78
110
79
- * Casting between two integers of the same size (e.g. i32 -> u32) is a no-op
111
+ <!-- * Casting between two integers of the same size (e.g. i32 -> u32) is a no-op
80
112
* Casting from a larger integer to a smaller integer (e.g. u32 -> u8) will
81
113
truncate
82
114
* Casting from a smaller integer to a larger integer (e.g. u8 -> u32) will
@@ -95,73 +127,116 @@ The semantics of numeric casts are:
95
127
* **[NOTE: currently this will cause Undefined Behavior if the value
96
128
is finite but larger or smaller than the largest or smallest finite
97
129
value representable by f32][float-float]**. This is a bug and will
98
- be fixed.
130
+ be fixed. -->
131
+ * サイズの同じ二つの整数間のキャスト (例えば、i32 -> u32) は何も行いません
132
+ * サイズの大きい整数から小さい整数へのキャスト (例えば、u32 -> u8) では切り捨てを行います
133
+ * サイズの小さい整数から大きい整数へのキャスト (例えば、u8 -> u32) では、
134
+ * 元の整数が符号無しならば、ゼロ拡張を行います
135
+ * 元の整数が符号付きならば、符号拡張を行います
136
+ * 浮動小数点数から整数へのキャストでは、0方向への丸めを行います
137
+ * ** [ 注意: 現在、丸められた値がキャスト先の整数型で扱えない場合、このキャストは未定義動作を引き起こします。] [ float-int ] **
138
+ これには Inf や NaN も含まれます。
139
+ これはバグであり、修正される予定です。
140
+ * 整数から浮動小数点数へのキャストでは、必要に応じて丸めが行われて、その整数を表す浮動小数点数がつくられます
141
+ (丸め戦略は指定されていません)
142
+ * f32 から f64 へのキャストは完全で精度は落ちません
143
+ * f64 から f32 へのキャストでは、表現できる最も近い値がつくられます
144
+ (丸め戦略は指定されていません)
145
+ * ** [ 注意: 現在、値が有限でありながらf32 で表現できる最大(最小)の有限値より大きい(小さい)場合、このキャストは未定義動作を引き起こします。] [ float-float ] **
146
+ これはバグであり、修正される予定です。
99
147
100
148
[ float-int ] : https://github.com/rust-lang/rust/issues/10184
101
149
[ 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
150
+
151
+ <!-- ## Pointer casts -->
152
+ ## ポインタキャスト
153
+
154
+ <!-- Perhaps surprisingly, it is safe to cast [raw pointers](raw-pointers.md) to and
106
155
from integers, and to cast between pointers to different types subject to
107
- some constraints. It is only unsafe to dereference the pointer:
156
+ some constraints. It is only unsafe to dereference the pointer: -->
157
+ 驚くかもしれませんが、いくつかの制約のもとで、 [ 生ポインタ] ( raw-pointers.md ) と整数の間のキャストや、ポインタと他の型の間のキャストは安全です。
158
+ 安全でないのはポインタの参照外しだけなのです。
108
159
109
160
``` rust
110
- let a = 300 as * const char ; // a pointer to location 300
161
+ # // let a = 300 as *const char; // a pointer to location 300
162
+ let a = 300 as * const char ; // 300番地へのポインタ
111
163
let b = a as u32 ;
112
164
```
113
165
114
- ` e as U ` is a valid pointer cast in any of the following cases:
166
+ <!-- `e as U` is a valid pointer cast in any of the following cases: -->
167
+ ` e as U ` が正しいポインタキャストであるのは、以下の場合です。
115
168
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*
169
+ <!-- * `e` has type `*T`, `U` has type `*U_0`, and either `U_0: Sized` or
170
+ `unsize_kind(T) == unsize_kind(U_0)`; a *ptr-ptr-cast* -->
171
+ * ` e ` が型 ` *T ` を持ち、 ` U ` が ` *U_0 ` であり、 ` U_0: Sized ` または ` unsize_kind(T) == unsize_kind(U_0) ` である場合; * ptr-ptr-cast*
120
172
121
- * ` e ` is an integer and ` U ` is ` *U_0 ` , while ` U_0: Sized ` ; * addr-ptr-cast*
173
+ <!-- * `e` has type `*T` and `U` is a numeric type, while `T: Sized`; *ptr-addr-cast* -->
174
+ * ` e ` が型 ` *T ` を持ち、 ` U ` が数値型で、 ` T: Sized ` である場合; * ptr-addr-cast*
122
175
123
- * ` e ` has type ` &[T; n] ` and ` U ` is ` *const T ` ; * array-ptr-cast*
176
+ <!-- * `e` is an integer and `U` is `*U_0`, while `U_0: Sized`; *addr-ptr-cast* -->
177
+ * ` e ` が整数、` U ` が ` *U_0 ` であり、 ` U_0: Sized ` である場合; * addr-ptr-cast*
124
178
125
- * ` e ` is a function pointer type and ` U ` has type ` *T ` ,
126
- while ` T: Sized ` ; * fptr -ptr-cast*
179
+ <!-- * `e` has type `&[T; n]` and `U` is `*const T`; *array-ptr-cast* -->
180
+ * ` e ` が型 ` &[T; n] ` を持ち、 ` U ` が ` *const T ` である場合 ; * array -ptr-cast*
127
181
128
- * ` e ` is a function pointer type and ` U ` is an integer; * fptr-addr-cast*
182
+ <!-- * `e` is a function pointer type and `U` has type `*T`,
183
+ while `T: Sized`; *fptr-ptr-cast* -->
184
+ * ` e ` が関数ポインタ型であり、 ` U ` が ` *T ` であって、` T: Sized ` の場合; * fptr-ptr-cast*
129
185
186
+ <!-- * `e` is a function pointer type and `U` is an integer; *fptr-addr-cast* -->
187
+ * ` e ` が関数ポインタ型であり、 ` U ` が整数である場合; * fptr-addr-cast*
130
188
131
189
# ` transmute `
132
190
133
- ` as ` only allows safe casting, and will for example reject an attempt to
134
- cast four bytes into a ` u32 ` :
191
+ <!-- `as` only allows safe casting, and will for example reject an attempt to
192
+ cast four bytes into a `u32`: -->
193
+ ` as ` は安全なキャストしか許さず、例えば4つのバイト値を ` u32 ` へキャストすることはできません。
135
194
136
195
``` rust,ignore
137
196
let a = [0u8, 0u8, 0u8, 0u8];
138
197
139
- let b = a as u32; // four eights makes 32
198
+ # // let b = a as u32; // four eights makes 32
199
+ let b = a as u32; // 4つの8で32になる
140
200
```
141
201
142
- This errors with:
202
+ <!-- This errors with: -->
203
+ これは以下のようなメッセージがでて、エラーになります。
143
204
144
- ``` text
205
+ <!-- ```text
145
206
error: non-scalar cast: `[u8; 4]` as `u32`
146
207
let b = a as u32; // four eights makes 32
147
208
^~~~~~~~
209
+ ``` -->
210
+ ``` text
211
+ error: non-scalar cast: `[u8; 4]` as `u32`
212
+ let b = a as u32; // 4つの8で32になる
213
+ ^~~~~~~~
148
214
```
149
215
150
- This is a ‘non-scalar cast’ because we have multiple values here: the four
216
+ <!-- This is a ‘non-scalar cast’ because we have multiple values here: the four
151
217
elements of the array. These kinds of casts are very dangerous, because they
152
218
make assumptions about the way that multiple underlying structures are
153
- implemented. For this, we need something more dangerous.
219
+ implemented. For this, we need something more dangerous. -->
220
+ これは「non-scalar cast」であり、複数の値、つまり配列の4つの要素、があることが原因です。
221
+ この種類のキャストはとても危険です。
222
+ なぜなら、複数の裏に隠れた構造がどう実装されているかについて仮定をおいているからです。
223
+ そのためもっと危険なものが必要になります。
154
224
155
- The ` transmute ` function is provided by a [ compiler intrinsic] [ intrinsics ] , and
225
+ <!-- The `transmute` function is provided by a [compiler intrinsic][intrinsics], and
156
226
what it does is very simple, but very scary. It tells Rust to treat a value of
157
227
one type as though it were another type. It does this regardless of the
158
- typechecking system, and just completely trusts you.
228
+ typechecking system, and just completely trusts you. -->
229
+ ` transmute ` 関数は [ コンパイラ intrinsic] [ intrinsics ] によって提供されており、やることはとてもシンプルながら、とても恐ろしいです。
230
+ この関数は、Rustに対し、ある型の値を他の型であるかのように扱うように伝えます。
231
+ これは型検査システムに関係なく行われ、完全に使用者頼みです。
159
232
160
233
[ intrinsics ] : intrinsics.html
161
234
162
- In our previous example, we know that an array of four ` u8 ` s represents a ` u32 `
235
+ <!-- In our previous example, we know that an array of four `u8`s represents a `u32`
163
236
properly, and so we want to do the cast. Using `transmute` instead of `as`,
164
- Rust lets us:
237
+ Rust lets us: -->
238
+ 先ほどの例では、4つの ` u8 ` からなる配列が ちゃんと ` u32 ` を表していることを知った上で、キャストを行おうとしました。
239
+ これは、` as ` の代わりに ` transmute ` を使うことで、次のように書けます。
165
240
166
241
``` rust
167
242
use std :: mem;
@@ -173,15 +248,22 @@ unsafe {
173
248
}
174
249
```
175
250
176
- We have to wrap the operation in an ` unsafe ` block for this to compile
251
+ <!-- We have to wrap the operation in an `unsafe` block for this to compile
177
252
successfully. Technically, only the `mem::transmute` call itself needs to be in
178
253
the block, but it's nice in this case to enclose everything related, so you
179
254
know where to look. In this case, the details about `a` are also important, and
180
255
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:
256
+ is too far away, and wrapping all of the code in `unsafe` isn't a great idea. -->
257
+ コンパイルを成功させるために、この操作は ` unsafe ` ブロックでくるんであります。
258
+ 技術的には、 ` mem::transmute ` の呼び出しのみをブロックに入れればいいのですが、今回はどこを見ればよいかわかるよう、関連するもの全部を囲んでいます。
259
+ この例では ` a ` に関する詳細も重要であるため、ブロックにいれてあります。
260
+ ただ、文脈が離れすぎているときは、こう書かないこともあるでしょう。
261
+ そういうときは、コード全体を ` unsafe ` でくるむことは良い考えではないのです。
262
+
263
+ <!-- While `transmute` does very little checking, it will at least make sure that
264
+ the types are the same size. This errors: -->
265
+ ` transmute ` はほとんどチェックを行わないのですが、最低限、型同士が同じサイズかの確認はします。
266
+ そのため、次の例はエラーになります。
185
267
186
268
``` rust,ignore
187
269
use std::mem;
@@ -193,11 +275,13 @@ unsafe {
193
275
}
194
276
```
195
277
196
- with:
278
+ <!-- with: -->
279
+ エラーメッセージはこうです。
197
280
198
281
``` text
199
282
error: transmute called with differently sized types: [u8; 4] (32 bits) to u64
200
283
(64 bits)
201
284
```
202
285
203
- Other than that, you're on your own!
286
+ <!-- Other than that, you're on your own! -->
287
+ ただそれ以外に関しては、自己責任です!
0 commit comments