如何从Option :: unwrap_or返回一个新结构?

Ian*_*ews 5 struct lifetime rust

我有一个HashMap,它使用a char作为键,使用a 作为struct值.

HashMap的get()方法通常会使用不在HashMap中的键来调用,因此我想unwrap_or()在返回的Option上使用它来创建默认struct值.但是,当我尝试这样做时,编译器抛出以下错误(temp作为我试图返回的默认值):

lib.rs:51:4: 51:8 error: `temp` does not live long enough
Run Code Online (Sandbox Code Playgroud)

这是一个小型的复制品:

struct Sample {
    thing: i32
}

fn do_stuff() {
    let map = HashMap::<char, Sample>::new();

    let sample = map.get(&'a').unwrap_or({
        let temp = Sample {
            thing : 0
        };
        &temp
    });
}
Run Code Online (Sandbox Code Playgroud)

我有两个问题:

  1. 有没有办法让temp绑定活得更久?
  2. struct使用选项时是否有更好的方法可以回退到默认值?

Eli*_*man 5

对于您的精确场景,您可以执行以下操作:

use std::collections::HashMap;
struct Sample {
    thing : i32
}

fn main() {
    let map = HashMap::<char, Sample>::new();
    let temp = Sample { thing : 0 };
    let sample = map.get(&'a').unwrap_or(&temp);
}
Run Code Online (Sandbox Code Playgroud)

但通常情况下,您想要的东西更像是这样的:

use std::collections::HashMap;
#[derive(Clone)]
struct Sample {
    thing : i32
}

fn get_sample(map: &HashMap<char, Sample>) -> Sample
{
    map.get(&'a').cloned().unwrap_or_else(|| {
        Sample { thing : 0 }
    })
}
Run Code Online (Sandbox Code Playgroud)

如果您确实想有条件地初始化并获取局部变量的地址,这是可能的,但不能使用 unwrap_oror 编写unwrap_or_else

use std::collections::HashMap;
struct Sample {
    thing : i32
}

fn main() {
    let map = HashMap::<char, Sample>::new();
    let temp;
    let sample = match map.get(&'a') {
        Some(sample) => sample,
        None => {
            temp = Sample { thing : 0 };
            &temp
        }
    };
}
Run Code Online (Sandbox Code Playgroud)