11% 型間のキャスト
22<!-- % Casting Between Types -->
33
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
55different types between each other. The first, `as`, is for safe casts.
66In 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における最も危険なフィーチャの一つです!
811
9- # Coercion
12+ <!-- # Coercion -->
13+ # 型強制
1014
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 ` ] ( #明示的型強制 ) で書くこともできます。
1318
14- Coercion occurs in ` let ` , ` const ` , and ` static ` statements; in
19+ <!-- Coercion occurs in `let`, `const`, and `static` statements; in
1520function call arguments; in field values in struct initialization; and in a
16- function result.
21+ function result. -->
22+ 型強制が現れるのは、 ` let ` ・ ` const ` ・ ` static ` 文、関数呼び出しの引数、構造体初期化の際のフィールド値、そして関数の結果です。
1723
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+ 一番よくある型強制は、参照からミュータビリティを取り除くものです。
1926
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 ` へ
2429
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 ) からミュータビリティを取り除くものがあります。
2833
29- * ` &T ` to ` *const T `
34+ <!-- * `*mut T` to `*const T` -->
35+ * ` *mut T ` から ` *const T ` へ
3036
31- * ` &mut T ` to ` *mut T `
37+ <!-- References can also be coerced to raw pointers: -->
38+ 参照も同様に、生ポインタへ型強制できます。
3239
33- Custom coercions may be defined using [ ` Deref ` ] ( deref-coercions.md ) .
40+ <!-- * `&T` to `*const T` -->
41+ * ` &T ` から ` *const T ` へ
3442
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` -->
3753# ` as `
3854
39- The ` as ` keyword does safe casting:
55+ <!-- The `as` keyword does safe casting: -->
56+ ` as ` というキーワードは安全なキャストを行います。
4057
4158``` rust
4259let x : i32 = 5 ;
4360
4461let y = x as i64 ;
4562```
4663
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+ 明示的型強制、数値型間のキャスト、そして、ポインタキャストです。
4968
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
5170expression, `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 ` へ型強制されるときのみです。)
5375
5476
55- ## Explicit coercions
77+ <!-- ## Explicit coercions -->
78+ ## 明示的型強制
5679
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 ` に型強制されるとき、有効です。
5882
59- ## Numeric casts
83+ <!-- ## Numeric casts -->
84+ ## 数値キャスト
6085
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 ` というキャストは、以下のような場合も有効です。
6288
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+ 例えば、
70101
71102``` rust
72103let one = true as u8 ;
73104let at_sign = 64 as char ;
74105let two_hundred = - 56i8 as u8 ;
75106```
76107
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+ これはバグであり、修正される予定です。
99148
100149[ float-int ] : https://github.com/rust-lang/rust/issues/10184
101150[ 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
106156from 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+ 安全でないのはポインタの参照外しだけなのです。
108160
109161``` 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番地へのポインタ
111164let b = a as u32 ;
112165```
113166
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 ` が正しいポインタキャストであるのは、以下の場合です。
115169
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*
120173
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*
122176
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*
124179
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*
127182
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*
129186
187+ <!-- * `e` is a function pointer type and `U` is an integer; *fptr-addr-cast* -->
188+ * ` e ` が関数ポインタ型であり、 ` U ` が整数である場合; * fptr-addr-cast*
130189
131190# ` transmute `
132191
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 ` へキャストすることはできません。
135195
136196``` rust,ignore
137197let a = [0u8, 0u8, 0u8, 0u8];
138198
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になる
140201```
141202
142- This errors with:
203+ <!-- This errors with: -->
204+ これは以下のようなメッセージがでて、エラーになります。
143205
144- ``` text
206+ <!-- ```text
145207error: non-scalar cast: `[u8; 4]` as `u32`
146208let b = a as u32; // four eights makes 32
147209 ^~~~~~~~
210+ ``` -->
211+ ``` text
212+ error: non-scalar cast: `[u8; 4]` as `u32`
213+ let b = a as u32; // 4つの8で32になる
214+ ^~~~~~~~
148215```
149216
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
151218elements of the array. These kinds of casts are very dangerous, because they
152219make 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+ そのためもっと危険なものが必要になります。
154225
155- The ` transmute ` function is provided by a [ compiler intrinsic] [ intrinsics ] , and
226+ <!-- The `transmute` function is provided by a [compiler intrinsic][intrinsics], and
156227what it does is very simple, but very scary. It tells Rust to treat a value of
157228one 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+ これは型検査システムに関係なく行われ、完全に使用者頼みです。
159233
160234[ intrinsics ] : intrinsics.html
161235
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`
163237properly, 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 ` を使うことで、次のように書けます。
165241
166242``` rust
167243use std :: mem;
@@ -173,15 +249,22 @@ unsafe {
173249}
174250```
175251
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
177253successfully. Technically, only the `mem::transmute` call itself needs to be in
178254the block, but it's nice in this case to enclose everything related, so you
179255know where to look. In this case, the details about `a` are also important, and
180256so 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+ そのため、次の例はエラーになります。
185268
186269``` rust,ignore
187270use std::mem;
@@ -193,11 +276,13 @@ unsafe {
193276}
194277```
195278
196- with:
279+ <!-- with: -->
280+ エラーメッセージはこうです。
197281
198282``` text
199283error: transmute called with differently sized types: [u8; 4] (32 bits) to u64
200284(64 bits)
201285```
202286
203- Other than that, you're on your own!
287+ <!-- Other than that, you're on your own! -->
288+ ただそれ以外に関しては、自己責任です!
0 commit comments