Prompt

?演算子はOption型で使用できる?Result以外で使える型は?

結論から言うと、Option 型でも ? 演算子はバッチリ使えるぜ!

むしろ、Rust のモダンなコードでは Result と同じくらい頻繁に Option に対して ? が使われているんだ。情報工学的に言うと、?Result 専用ではなく、「特定のトレイトを実装した型」なら何でも使える 汎用的な仕組みなんだぜ。


1. Option での挙動

Option に対して ? を使うと、次のような動きになる。

  • Some(値) の場合: 中身の「値」を取り出して、処理を続行する。

  • None の場合: 即座に関数を終了し、呼び出し元に None を返す

Rust

fn get_user_name(id: u32) -> Option<String> {
    // find_user が None を返したら、この関数自体がここで None を返して終了する
    let user = find_user(id)?; 
    
    // user.name が None なら、ここで None を返して終了
    let name = user.name?; 

    Some(name)
}

2. Result 以外で使える型は?(Try トレイトの秘密)

「他には何に使えるの?」という質問への答えは、std::ops::Try トレイトを実装している型」 だ!

現在の Rust(安定版)で主に使えるのは以下の2つだね。

  1. Result<T, E>

  2. Option<T>

⚠️ 大事なルール:混ぜるな危険

? 演算子は 「今いる関数の戻り値の型」と同じ種類 の型にしか使えないんだ。

  • 戻り値が Option の関数内で、Result? は使えない。

  • 戻り値が Result の関数内で、Option? は使えない。

もし混ぜたい場合は、.ok()(ResultをOptionに変換)や .ok_or()(OptionをResultに変換)を使って型を揃えてあげる必要があるぜ!


3. 💡 見落とされがちな視点:Poll

君がさっき興味を持っていた async/await(Future)の世界では、std::task::Poll という型でも ? が使われることがあるよ。

  • Poll::Ready(Ok(v))? v を取り出す。

  • Poll::Pending ならそのまま Pending を返す。

低レイヤーな非同期処理を自分で書くようになると、この ? の便利さがさらに身に沁みるはずだ。


4. 🛠️ 自作の型で ? を使いたい!

「自分で作った型でも ? を使いたいな」と思うかもしれないけど、残念ながら Try トレイトは現時点では “unstable”(実験的機能) なんだ。

将来的に Rust のバージョンが上がれば、君が作ったオリジナルの「エラーっぽい状態を持つ型」にも ? を付けられる日が来るかもしれない。情報工学の進化を待つ楽しみの一つだね!


🏁 まとめ

  • Option でも ? は使える(None なら即 return)。

  • 使えるのは Try トレイト を実装した型だけ。

  • 現状は Result, Option, Poll あたりがメイン。

? を使いこなすと、ネストが深くなりがちな if let 地獄から脱出できて、コードがめちゃくちゃスタイリッシュになるぜ!

次は、この Option? を使って「ネストした JSON データから特定の値を一本道で取り出す」ような、実戦的なコードを書いてみる?😊✨

Would you like me to show you how to convert between Option and Result using .ok_or() so you can use ? freely?