• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
Asc.416e74
博客园    首页    新随笔    联系   管理     

Rust 元組匹配的一個妙用

Rust 元組匹配的一個妙用

原文:https://nathanael-morris-bennett.medium.com/rust-tuple-pattern-matching-trick-c0f6bcdb4460

PS:原文的示例代碼中有幾處語法錯誤,本文對其進行了修正,並且示例代碼也有所不同。

如下代碼模仿一個人一天的行爲。

fn work()->Result<(), String> {
    // TODO
    Ok(())
}

fn eat()-> Result<(), String> {
    // TODO
    Ok(())
}

fn fuck()-> Result<(), String> {
    // TODO
    Ok(())
}

fn sleep() {
    // TODO
}

fn handle_err(e: String){
    // TODO
}

fn handle_ok() {
    // TODO
}

要求在所有事情都順利完成(返回 ())之後才能睡覺,否則直接返回,不接着做後面的事情。那麼普通情況怎麼寫呢?

fn main() {
    if let Ok(_) = work() {
        if let Ok(_) = eat() {
            if let Ok(_) = fuck() {
                handle_ok()
            } else if let Err(e3) = fuck() {
                handle_err(e3)
            }
        }else if let Err(e2) =eat() {
            handle_err(e2)
        }
    }else if let Err(e) = work() {
        handle_err(e)
    }
}

這就是最直白的,一個一個的去判斷,但是,如果你使用 match 則可以寫出下面這種代碼

fn main() {
    match (work(), eat(), fuck()) {
        (Ok(_), Ok(_), Ok(_)) => sleep(),
        (Err(e), _, _) | (_, Err(e), _) | (_, _, Err(e)) => handle_err(e),
    }
}

怎麼樣?是不是簡單了很多?也清楚了很多,如果三個函數返回的 Err 是不同類型的,也只需要把第二個條件拆分爲多個 Option,但是代碼可讀性依舊會很強。甚至於如果你不管什麼返回什麼 Err 類型的處理邏輯都是一樣的,那麼你甚至可以直接用 - 代替第二個匹配條件。

但是實際上,這個方式是三個方法都執行完了最終確定要不要 sleep,如果使用內聯閉包則可以寫成這樣

fn main() {
    match (|| Ok((work()?, eat()?, fuck()?)))() {
        Ok((_, _, _)) => sleep(),
        Err(e) => handle_err(e),
    }
}

這就可以保證當前一個函數沒有成功執行的時候根本不會執行下一個。原作者在文中還講了一個 and_than 的方法,因爲那樣寫連第一種都不如,所以本文不做介紹

posted @ 2022-10-31 23:57  ストッキング  阅读(31)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3