2020-07-15 22:20:29
Rust 整数型でバリアント未指定の場合必ずi32が割り当てられるわけではないということ
コンパイル時に型が自動で決まるから
結論から言うとコンパイル時に型が自動で決まるからです。この記事を書いていると「まぁそういう仕様だからなあ」となってしまったのですが、折角書いたのでそのまま記事投稿します。何を不思議に思ったかで言うと以下の状況です。整数型でバリアント指定しない場合は基本的には i32
になるけど異なる場合もあるんだなという状況です。
let a = 100i32;
let b = 50u32;
// もちろんエラーになる
let c = a + b;
let a = 100;
let b = 50u32;
// ↓↓エラーにならない
let c = a + b;
// 変数a のバリアントは u32 になるみたい
バリアントとは
i32
, i16
とかのサイズ指定です。日本語版のThe Rust Programming Language にてバリアントとして表記されていましたのでそのまま表記します
異なるバリアントの整数型を混ぜたてエラーになる場合
変数aは符号なし8ビットで、変数bは符号なし32ビットの数値です。これを実行するとコンパイルエラーによって失敗します。
ソースコード
fn main() {
let a = 100u8;
let b = 50u32;
let c = a + b;
println!("{}", c);
}
実行結果
Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
--> src/main.rs:4:17
|
4 | let c = a + b;
| ^ expected `u8`, found `u32`
error[E0277]: cannot add `u32` to `u8`
--> src/main.rs:4:15
|
4 | let c = a + b;
| ^ no implementation for `u8 + u32`
|
= help: the trait `std::ops::Add<u32>` is not implemented for `u8`
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.
error: could not compile `playground`.
To learn more, run the command again with --verbose.
as
キーワードを使うことでバリアント変換
異なるバリアントの整数型を混ぜた加算をする場合 as
キーワードを使うことで変換することが可能になるようです。
ソースコード
fn main() {
let a = 100u8;
let b = 50u32;
let c = a as u32 + b;
println!("{}", c);
}
実行結果
150
バリアント指定がない場合はi32
になる
Rustの整数型でバリアント指定が無い場合は符号付き32ビットの i32
になるようです。
では、どの整数型を使うべきかはどう把握すればいいのでしょうか?もし確信が持てないのならば、 Rustの基準型は一般的にいい選択肢になります。整数型の基準はi32型です: 64ビットシステム上でも、 この型が普通最速になります。
引用元: https://doc.rust-jp.rs/book/second-edition/ch03-02-data-types.html
バリアント指定無し整数とバリアント指定有り整数を混ぜると?
コンパイルエラーにはならないようです。以下の引用にある通りコンパイル時にはバリアント指定されている変数bに合わせたバリアントが変数aに設定されるのでしょう。てっきり i32
のバリアントが設定されるかと思いましたが、使用方法に基づいたバリアントが指定されるようです。
Rustは静的型付き言語であることを弁えておいてください。つまり、 コンパイル時に全ての変数の型が判明している必要があるということです。コンパイラは通常、値と使用方法に基づいて、 使用したい型を推論してくれます。
引用元: https://doc.rust-jp.rs/book/second-edition/ch03-02-data-types.html
ソースコード
fn main() {
let a = 100;
let b = 50u32;
let c = a + b;
println!("{}", c);
}
実行結果
150