我想知道是否有一种优雅的解决方案来获取类似于unwrap_or_else在Option<&T>上的代码/行为。我的用例是将可选的引用传递给一个函数,如果没有使用,则创建同一类型的默认值以供使用。这是我代码的简化版本:
#[derive(Debug)]
struct ExpensiveUnclonableThing {}
fn make_the_thing() -> ExpensiveUnclonableThing {
// making the thing is slow
// ...
ExpensiveUnclonableThing {}
}
fn use_the_thing(thing_ref: &ExpensiveUnclonableThing) {
dbg!(thing_ref);
}
fn use_or_default(thing_ref_opt: Option<&ExpensiveUnclonableThing>) {
enum MaybeDefaultedRef<'a> {
Passed(&'a ExpensiveUnclonableThing),
Defaulted(ExpensiveUnclonableThing),
}
let thing_md = match thing_ref_opt {
Some(thing_ref) => MaybeDefaultedRef::Passed(thing_ref),
None => MaybeDefaultedRef::Defaulted(make_the_thing()),
};
let thing_ref = match &thing_md {
MaybeDefaultedRef::Passed(thing) => thing,
MaybeDefaultedRef::Defaulted(thing) => thing,
};
use_the_thing(thing_ref);
}
fn use_or_default_nicer(thing_ref_opt: Option<&ExpensiveUnclonableThing>) {
let thing_ref = thing_ref_opt.unwrap_or_else(|| &make_the_thing());
use_the_thing(thing_ref);
}
fn main() {
let thing = make_the_thing();
use_or_default(Some(&thing));
use_or_default(None);
use_or_default_nicer(Some(&thing));
use_or_default_nicer(None);
}
当unwrap_or_else闭包结束时,该对象会立即丢弃,因此当我尝试这样做时会收到错误提示:无法执行该操作。
error[E0515]: cannot return reference to temporary value
--> src/main.rs:31:53
|
31 | let thing_ref = thing_ref_opt.unwrap_or_else(|| &make_the_thing());
| ^----------------
| ||
| |temporary value created here
| returns a reference to data owned by the current function
什么是 Rust 的“惯用方式”来编写 use_or_default?除了创建一个通用的 MaybeDefaultedRef 类型并带有一些便利方法外,还有没有其他方法可以使其看起来类似于 use_or_default_nicer 的实现?如果有更好的方法,我愿意重构整个东西。