Rust error[E0308]: mismatched types — コンパイル時の型不一致を修正する

beginner🦀 Rust2026-03-18| Rust 1.60以降(Linux、macOS、Windows)— rustcが動作する全プラットフォーム対応

Error Message

error[E0308]: mismatched types --> src/main.rs:5:18 | 5 | let x: i32 = "hello"; | --- ^^^^^^^ expected `i32`, found `&str`
#rust#型システム#型不一致#コンパイラ#

エラーの内容

cargo build を実行すると、コンパイラが処理を止めます:

error[E0308]: mismatched types
  --> src/main.rs:5:18
   |
5  |     let x: i32 = "hello";
   |            ---   ^^^^^^^ expected `i32`, found `&str`
   |
   = note: expected type `i32`
              found type `&str`

ビルドが失敗します。Rustは型不一致のあるコードをコンパイルしません — 暗黙の型変換も、暗黙のキャストも、「だいたい合っていればOK」という処理も一切ありません。変数 xi32 として宣言されていますが、文字列リテラルが代入されています。Rustではこれは完全なエラーです。

なぜこのエラーが発生するのか

Rustは静的型付け言語です。すべての変数はコンパイル時に厳密にひとつの型を持ちます。間違った型を代入すると、コンパイラは容赦なく拒否します。例外はありません。

これは実際のバグを早期に検出するための仕組みです。Cでの暗黙の型変換は警告なしに64ビット値を32ビットに切り捨てることがありますが、Rustは明示的な処理を強制します。その代わり、型について曖昧にはできません — それがRustの設計思想です。

主な発生原因:

  • 代入する値に対して変数の型アノテーションが間違っている
  • 関数から間違った型を返している
  • String が期待される場所に &str を渡している(またはその逆)
  • i32u32usize などの整数型を混在させている
  • 裸の T が期待される場所で Option<T> の値を使っている

修正方法

修正1: 型アノテーションを修正する

値は正しいがアノテーションが間違っている場合は、アノテーションを修正します:

// 修正前(アノテーションが間違っている)
let x: i32 = "hello";   // error: expected i32, found &str

// 修正後(アノテーションが値と一致している)
let x: &str = "hello";  // OK
// またはRustに型推論させる
let x = "hello";        // &str として推論される

修正2: 値を修正する

型アノテーションが意図通りであれば、正しい値を代入します:

// 文字列ではなく整数が必要だった場合
let x: i32 = 42;        // OK

修正3: 明示的に変換する

型を変換する必要がある場合、Rustは明示的な変換を要求します。状況に合ったものを選んでください:

// &str → String
let s: String = "hello".to_string();
let s: String = String::from("hello");

// String → &str
let owned = String::from("hello");
let borrowed: &str = &owned;

// i64 → i32(値が2_147_483_647を超える場合は切り捨て)
let big: i64 = 100;
let small: i32 = big as i32;

// String → 整数
let n: i32 = "42".parse().unwrap();
// より安全な書き方 — 失敗時の理由が分かる:
let n: i32 = "42".parse().expect("not a valid number");

よくあるケース

関数の戻り値の型不一致

末尾のセミコロンがあると、戻り値の型が暗黙的に () に変わります。セミコロンを削除してください:

// error: expected i32, found ()
fn get_value() -> i32 {
    let x = 42;
    // xを返し忘れている — またはxの後にセミコロンが付いている
}

// 修正: 最後の式のセミコロンを削除する
fn get_value() -> i32 {
    let x = 42;
    x  // 暗黙のreturn — セミコロンなし
}

整数型の混在

Vec::len()i32 ではなく usize を返します。初心者がよくつまずくポイントです:

fn print_length(v: &Vec<i32>) {
    let len: i32 = v.len();  // error: expected i32, found usize
}

// 修正: 正しい型を使うか、明示的にキャストする
fn print_length(v: &Vec<i32>) {
    let len: usize = v.len();        // 正しい型
    let len2: i32 = v.len() as i32; // 明示的なキャスト(小さいVecなら安全)
}

Optionのアンラップ

Iterator::next()T ではなく Option<T> を返します。Optionを伝播させるか、フォールバックを用意してください:

fn first_char(s: &str) -> char {
    s.chars().next()  // error: expected char, found Option<char>
}

// 方法1: 戻り値の型をOptionに変更して伝播させる
fn first_char(s: &str) -> Option<char> {
    s.chars().next()
}
// 方法2: 空文字列のデフォルト値でアンラップする
fn first_char(s: &str) -> char {
    s.chars().next().unwrap_or('\0')
}

構造体フィールドの型不一致

struct User {
    age: u32,
}

// error: expected u32, found i32
let user = User { age: -1i32 };

// 修正: 有効なu32の値を使う
let user = User { age: 25u32 };

エラーメッセージの読み方

Rustのコンパイラは正確な場所と関係する両方の型を表示します。読み方は次の通りです:

error[E0308]: mismatched types
  --> src/main.rs:5:18
   |
5  |     let x: i32 = "hello";
   |            ---   ^^^^^^^ expected `i32`, found `&str`
   |            |
   |            expected due to this type annotation
  • src/main.rs:5:18 — ファイル名、5行目、18列目(型不一致の場所)
  • i32 の下の --- — 宣言された型
  • "hello" の下の ^^^^^^^ — 問題のある値
  • expected X, found Y — Xはコンテキストが要求する型、Yは実際に渡した型

Expected(期待された型) はアノテーション、関数シグネチャ、構造体フィールドなどのコンテキストが要求する型です。Found(実際の型) は記述したコードの実際の型です。どちらか一方をもう一方に合わせて修正してください。

型推論に任せる

関数の戻り値の型が分からない場合は、アノテーションを省略してRustに推論させましょう:

// Rustに型を推論させる
let x = some_function();

// 実際の型を知りたい場合は、意図的にエラーを起こす:
let _: () = some_function();  // Rustが実際の型を教えてくれる

エラーには expected (), found SomeType と表示され、実際に推論された型が分かります。IDEなしで素早く型を調べられる便利なテクニックです。

動作確認

cargo build を実行します。ビルドが成功した場合の出力は次の通りです:

   Compiling myproject v0.1.0 (/path/to/myproject)
    Finished dev [unoptimized + debuginfo] target(s) in 0.42s

出力に error[E0308] が含まれていなければ修正完了です。テストがある場合は合わせて実行しましょう:

cargo test

Related Error Notes