有没有一种优雅的方法可以使用“匹配”语句重写获取或创建选项?

Is there an elegant way to rewrite getting or creating an Option using a `match` statement?

我将我的代码归结为以下几行:

#[derive(Debug)]
struct Config {
    values: Vec<String>,
    compiled: Option<Vec<String>>,
}

impl Config {
    fn comp_values(&mut self) -> &Vec<String> {
        if self.compiled.is_none() {
            self.compiled = Some(self.values.clone());
        }
        self.compiled.as_ref().unwrap()
    }

    fn comp_values_match(&mut self) -> &Vec<String> {
        match self.compiled {
            Some(_) => self.compiled.as_ref().unwrap(),
            None => {
                self.compiled = Some(self.values.clone());
                self.compiled.as_ref().unwrap()
            }
        }
    }
}

fn main() {
    let mut c = Config {
        values: vec![String::from("a"), String::from("b")],
        compiled: None,
    };
    println!("config before: {:?}", c);
    println!("compiled: {:?}", c.comp_values());
    println!("config after: {:?}", c);
}

我想要的是:

match self.compiled {
    Some(v) => v,
    None => {
        // assemble v and assign it to self.compiled
        v
    },
}

就像书中的closure chapter一样。有没有可能在书中它只起作用,因为 u32 实现了 Copy 特性?如果我将 match 行更改为 match self.compiled.as_ref(),则 Some(v) => v, 有效。在 None 臂中,我不能像 self.compiled = ... 那样分配,因为我在该块中有变量 'open'(或用 self.compiled.as_ref() 引用)。

我的假设是否正确?在这种情况下,comp_values() 方法是最优雅的解决方案吗?

不是 match 语句,但我认为您正在寻找 get_or_insert_with