首页 > 解决方案 > 模式匹配如何与 Rust 中的 ref 一起工作?

问题描述

刚刚从这里遇到了这段代码:

...
    let mut txn = client.transaction()?;
    loop {
        let mut sp = txn.savepoint("cockroach_restart")?;
        match op(&mut sp).and_then(|t| sp.commit().map(|_| t)) {
            Err(ref err)
                if err
                    .code()
                    .map(|e| *e == SqlState::T_R_SERIALIZATION_FAILURE)
                    .unwrap_or(false) => {}
            r => break r,
        }
    }
    .and_then(|t| txn.commit().map(|_| t))
...

目前还不清楚街区内发生了什么match

  1. 为什么处理后没有处理Ok变体Err
  2. 从哪里来r
  3. 有什么逻辑err.code()...?它是从指针到 bool 的映射,然后在 bool 上展开???然后什么都不做?

标签: rustcockroachdb

解决方案


为什么处理后没有处理Ok变体Err

匹配的第二个分支是一个匹配任何值的包罗万象的模式,因此它涵盖了Ok变体,以及Err第一个变体中的保护失败的变体。

从哪里来r

当标识符 liker用作模式时,它表示捕获匹配值的新局部变量。

……的逻辑是什么err.code()

postgres::Error::code()返回一个Option<&SqlState>. 如果提供了代码(选项是Some),并且等于SqlState::T_R_SERIALIZATION_FAILURE,则循环继续。如果T_R_SERIALIZATION_FAILURE未提供或未提供(选项为None),则匹配保护返回 false 并改为执行 catch-all 模式,停止循环。

code()逐步解开处理:

  • postgres::Error::code()返回Option<&SqlState>
  • Option<&SqlState>::map(closure)映射Option<&SqlState>Option<type returned by the closure>. 仅在选项为时才调用闭合Some,否则Option::map仅返回None。由于我们的闭包只计算 a ==,所以它返回boolmap因此返回Option<bool>。(闭包必须*用来取消引用该值,因为它接收到&SqlState.)
  • Option<bool>::unwrap_or(default_value)如果选项是Some,则计算选项中的值,default_value如果是None,则有效地转换Option<bool>为 a bool,这是我们需要的if.

推荐阅读