温馨提示:本文翻译自stackoverflow.com,查看原文请点击:rust - How to get an Option's value or set it if it's empty?
rust

rust - 如何获得期权的价值或设置它为空?

发布于 2020-04-07 11:06:41

我想获得name如果不为空或设置一个新值。我怎样才能做到这一点?

#[derive(Debug)]
struct App {
    name: Option<String>,
    age: i32,
}

impl App {
    fn get_name<'a>(&'a mut self) -> &'a Option<String> {
        match self.name {
            Some(_) => &self.name,
            None => {
                self.name = Some(String::from("234"));
                &self.name
            }
        }
    }
}

fn main() {
    let mut app = App {
        name: None,
        age: 10,
    };

    println!("{:?} and name is {}", &app, &app.get_name().unwrap())
}

我得到的错误是:

error[E0507]: cannot move out of borrowed content
  --> src/main.rs:25:44
   |
25 |     println!("{:?} and name is {}", &app, &app.get_name().unwrap())
   |                                            ^^^^^^^^^^^^^^ cannot move out of borrowed content

error[E0502]: cannot borrow `app` as mutable because it is also borrowed as immutable
  --> src/main.rs:25:44
   |
25 |     println!("{:?} and name is {}", &app, &app.get_name().unwrap())
   |     ---------------------------------------^^^---------------------
   |     |                                |     |
   |     |                                |     mutable borrow occurs here
   |     |                                immutable borrow occurs here
   |     immutable borrow ends here
   |
   = note: this error originates in a macro outside of the current crate

查看更多

提问者
Aqrun
被浏览
91
211k 2018-02-10 04:19

在我看来就像您想要的get_or_insert_with()方法这将在Optionis 时执行闭包,并将None结果用作新值:

fn get_name(&mut self) -> String {
    self.name.get_or_insert_with(|| String::from("234"))
}

如果您已经有要插入的值,或者创建该值并不昂贵,则也可以使用get_or_insert()方法

fn get_name(&mut self) -> &String {
    self.name.get_or_insert(String::from("234"))
}

您还需要更改main()功能以避免借用问题。一个简单的解决方案是派生Clone您的结构,然后.clone()调用它println!()

fn main() {
    let mut app = App {
        name: None,
        age: 10,
    };

    println!("{:?} and name is {}", app.clone(), app.get_name())
}