error[E0284]: type annotations needed

戻り値の型推論が失敗した場合について。

他エラーとの関係

このエラーは『E0282 - 型推論の失敗 - 1』と原理や対策が共通している。

パターン

パターン A

基本形

型推論のための情報が不足しているパターン。

サンプル


fn main() {
	let result = "42".parse();
    assert!(result.is_ok());
}

error[E0284]: type annotations needed for `Result<_, _>`
 --> src\main.rs:2:6
  |
2 |     let result = "42".parse();
  |         ^^^^^^        ----- type must be known at this point
  |
  = note: cannot satisfy `<_ as FromStr>::Err == _`
help: consider giving `result` an explicit type, where the type for type parameter `F` is specified
  |
2 |     let result: Result<F, _> = "42".parse();
  |               ++++++++++++++

解決策 1

エラーメッセージにもあるが、変数宣言で型を明示すればよい。


fn main() {
	let result: Result<i32, _> = "42".parse();
    assert!(result.is_ok());
}

解決策 2

値の生成時に型を明示する方法もある。


fn main() {
	let result = "42".parse::<i32>();
    assert!(result.is_ok());
}

パターン B

トレイトの選択

推論中の型を引数に、適用可能なトレイトを複数の候補から探る事はできない。

なぜなら、これをするとトレイトの候補や組合せが膨大な数になる場合がある。

そして、これは以下のサンプルであげるような少し意外な結果をもたらす。

サンプル

以下では、42 との比較で xi32 型だと分かりそうだが、これはエラーになる。なぜなら、== 演算子のためには Eq トレイトが必要になる。しかし、Eq トレイトには i32 のための実装だけでなく、他の型のための実装も存在する。


fn main() {
	let x = "42".parse().unwrap();
    assert!(x == 42);
}

error[E0284]: type annotations needed
 --> src\main.rs:2:9
  |
2 |     let x = "42".parse().unwrap();
  |         ^        ----- type must be known at this point
  |
  = note: cannot satisfy `<_ as FromStr>::Err == _`
help: consider giving `x` an explicit type
  |
2 |     let x: /* Type */ = "42".parse().unwrap();
  |          ++++++++++++

解決策

基本形と同じ解決策が使える。

他にも、トレイトのメソッド呼出を完全修飾記法に変更してもよい。