はじめに

事象には、以下の記載する

  • タイトルは主要なエラーメッセージ内容
  • エラーが発生する最小限コード
  • コンパイル結果

自分はRust初心者で、随時更新していきます。かなり簡単な内容も書いていきます。

エラー例

cannot use the ? operator in a function that returns ()

事象

use rustyline::Editor;

fn main() {
    let mut rl = Editor::<()>::new()?;
}
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
 --> src/main.rs:4:37
  |
3 | fn main() {
  | --------- this function should return `Result` or `Option` to accept `?`
4 |     let mut rl = Editor::<()>::new()?;
  |                                     ^ cannot use the `?` operator in a function that returns `()`
  |
  = help: the trait `FromResidual<Result<Infallible, ReadlineError>>` is not implemented for `()`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `s007-my` (bin "s007-my") due to previous error
[Finished running. Exit status: 101]

調査

  • ?演算子は、ResultまたはOptionを返す関数内でしか利用できない
  • ? 演算子は、「エラーがあったらreturnしてそうでないなら中の値が欲しい」ケースで便利
  • ?演算子はエラーを伝播する。今回はnew()?でエラーが発生した場合、それを伝播するため、main関数の()(=タプル型)は一致しないことになる。

解決策

use rustyline::Editor;
use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> {
    let mut rl = Editor::<()>::new()?;

    Ok(())
}

余談

Try Trait v2

以下のコードでret_okprint_if_okで、?演算子をつけて呼び出されていることから、Result型を返却する作りになっている。

fn ret_ok() -> Result<isize, ()> {
    Ok(10)
}

fn print_if_ok() -> Result<(), ()> {
    println!("{}", ret_ok()?);

    println!("print succeed");
    Ok(())
}

Try Trait v2はこれを明確な型を返却するように定義することが可能。

参考