🏷️

型システム — 動的型付けの自由を手放して得るもの

Rubyのダックタイピング vs Rustの静的型推論

Rubyでx = "hello"x = 42になっても何の問題もない。メソッドさえあればいい(ダックタイピング)。Rustではこれは不可能。

let x = "hello";  // コンパイラが&strと推論
// x = 42;  // コンパイルエラー!expected &str, found integer

基本型

RubyのIntegerFloatStringがRustではより細分化される。

Ruby Rust 説明
Integer i32, i64, u32, u64 符号/サイズ明示
Float f32, f64 32ビット/64ビット
true/false bool 同一
String String, &str 2種類(別ポスト)
nil なし(Option<T> 別ポスト
Symbol なし(enum使用) 別ポスト
Array Vec<T> ジェネリック
Hash HashMap<K, V> ジェネリック

i32は32ビット符号あり整数、u64は64ビット符号なし整数。Rubyではこんな区分を気にしたことがないが、Rustではメモリサイズと符号を明示する。

型推論

Rustは型を書かなくても大抵は推論してくれる。

let x = 42;          // i32と推論(デフォルト)
let y = 3.14;         // f64と推論(デフォルト)
let name = "sehwa";   // &strと推論
let nums = vec![1, 2, 3]; // Vec<i32>と推論

明示が必要な場合もある。コンパイラが判断できない状況だ。

// エラー — 42がi32かu64かわからない
let x = "42".parse(); // error: type annotations needed

// 明示的に教える
let x: i32 = "42".parse().unwrap();
// または
let x = "42".parse::<i32>().unwrap();  // turbofish構文

::<i32>をturbofishと呼ぶ。魚に見えるからだそうだ。Rustコミュニティ独特のネーミング。

タプルと配列

Rubyの配列はどんな型でも混ぜられる。[1, "hello", true]も問題ない。RustのVecは1つの型しか入らない。

複数の型をまとめたければタプルを使う。

let pair: (i32, &str) = (42, "hello");
println!("{}", pair.0);  // 42
println!("{}", pair.1);  // hello

Rubyのreturn a, bパターンがRustではタプルになる。

fn divide(a: f64, b: f64) -> (f64, f64) {
    (a / b, a % b)  // 商と余り
}
let (quotient, remainder) = divide(10.0, 3.0);

型変換 — asとFrom/Into

Rubyでは42.to_s"42".to_iで自由に変換できる。Rustには2つのアプローチがある。

// 数値間変換 — as(.to_i/.to_fに近い)
let x: i32 = 42;
let y: f64 = x as f64;

// 文字列→数値 — parse(失敗する可能性があるのでResult返却)
let n: i32 = "42".parse().unwrap();

// 数値→文字列 — to_string
let s: String = 42.to_string();

asは数値間変換でのみ使う。文字列変換はparse()to_string()。Rubyの.to_iと違い、parse()はResultを返すため変換失敗を無視できない

キーポイント

1

デフォルト整数型はi32、符号/サイズを明示する

2

型推論が強力で大抵は明示する必要がない

3

複数の型をまとめるにはタプル(i32, &str)を使う

4

型変換はas(数値)、parse()(文字列→数値)で明示的

メリット

  • 型エラーがコンパイル時に検出される — RubyのTypeErrorが消える
  • IDE自動補完が完璧に動作する — Rubyよりはるかに正確

デメリット

  • Rubyの自由な型切り替えができず最初はもどかしい
  • i32とi64を足すには明示的な変換が必要

ユースケース

性能に敏感なコードでi32 vs i64の選択が重要な時 外部データ(JSON、CSV)パース時の型変換処理

参考資料