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:
108+ <!-- The semantics of numeric casts are: -->
109+ 数値キャストのセマンティクスは以下の通りです。
78110
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
80112* Casting from a larger integer to a smaller integer (e.g. u32 -> u8) will
81113 truncate
82114* Casting from a smaller integer to a larger integer (e.g. u8 -> u32) will
@@ -95,73 +127,116 @@ The semantics of numeric casts are:
95127 * **[NOTE: currently this will cause Undefined Behavior if the value
96128 is finite but larger or smaller than the largest or smallest finite
97129 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+ これはバグであり、修正される予定です。
99147
100148[ float-int ] : https://github.com/rust-lang/rust/issues/10184
101149[ 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
106155from 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+ 安全でないのはポインタの参照外しだけなのです。
108159
109160``` 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番地へのポインタ
111163let b = a as u32 ;
112164```
113165
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 ` が正しいポインタキャストであるのは、以下の場合です。
115168
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*
120172
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*
122175
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*
124178
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*
127181
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*
129185
186+ <!-- * `e` is a function pointer type and `U` is an integer; *fptr-addr-cast* -->
187+ * ` e ` が関数ポインタ型であり、 ` U ` が整数である場合; * fptr-addr-cast*
130188
131189# ` transmute `
132190
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 ` へキャストすることはできません。
135194
136195``` rust,ignore
137196let a = [0u8, 0u8, 0u8, 0u8];
138197
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になる
140200```
141201
142- This errors with:
202+ <!-- This errors with: -->
203+ これは以下のようなメッセージがでて、エラーになります。
143204
144- ``` text
205+ <!-- ```text
145206error: non-scalar cast: `[u8; 4]` as `u32`
146207let b = a as u32; // four eights makes 32
147208 ^~~~~~~~
209+ ``` -->
210+ ``` text
211+ error: non-scalar cast: `[u8; 4]` as `u32`
212+ let b = a as u32; // 4つの8で32になる
213+ ^~~~~~~~
148214```
149215
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
151217elements of the array. These kinds of casts are very dangerous, because they
152218make 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+ そのためもっと危険なものが必要になります。
154224
155- The ` transmute ` function is provided by a [ compiler intrinsic] [ intrinsics ] , and
225+ <!-- The `transmute` function is provided by a [compiler intrinsic][intrinsics], and
156226what it does is very simple, but very scary. It tells Rust to treat a value of
157227one 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+ これは型検査システムに関係なく行われ、完全に使用者頼みです。
159232
160233[ intrinsics ] : intrinsics.html
161234
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`
163236properly, 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 ` を使うことで、次のように書けます。
165240
166241``` rust
167242use std :: mem;
@@ -173,15 +248,22 @@ unsafe {
173248}
174249```
175250
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
177252successfully. Technically, only the `mem::transmute` call itself needs to be in
178253the block, but it's nice in this case to enclose everything related, so you
179254know where to look. In this case, the details about `a` are also important, and
180255so 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+ そのため、次の例はエラーになります。
185267
186268``` rust,ignore
187269use std::mem;
@@ -193,11 +275,13 @@ unsafe {
193275}
194276```
195277
196- with:
278+ <!-- with: -->
279+ エラーメッセージはこうです。
197280
198281``` text
199282error: transmute called with differently sized types: [u8; 4] (32 bits) to u64
200283(64 bits)
201284```
202285
203- Other than that, you're on your own!
286+ <!-- Other than that, you're on your own! -->
287+ ただそれ以外に関しては、自己責任です!
0 commit comments