【发布时间】:2021-11-02 15:51:42
【问题描述】:
我正在尝试使用策略模式来使用不同的方法从输入列表中生成操作。
use rand::{prelude::SliceRandom, Rng};
#[derive(Debug, Clone)]
struct Inner {
num: usize,
}
#[derive(Debug)]
enum Outer {
ActionA(Inner),
ActionB(Inner),
}
fn main() {
// A method to generate an Outer from a list of Inners
type Strategy = Box<dyn Fn(&Vec<&Inner>) -> Box<dyn FnMut() -> Outer>>;
let random_strategy: Strategy = Box::new(|inners| {
let mut rng = rand::thread_rng();
Box::new(move || {
let inner = inners.choose(&mut rng).unwrap();
if rng.gen_bool(1.0 / 2.0) {
Outer::ActionA(inner.to_owned().clone())
} else {
Outer::ActionB(inner.to_owned().clone())
}
})
});
let inners = vec![&Inner { num: 3 }, &Inner { num: 4 }];
let get_choice = random_strategy(&inners);
for _ in 0..4 {
let choice = get_choice();
println!("{:?}", choice);
// do something...
}
}
每个策略都是一个闭包,因为它可能包含一些状态(为了保持示例简单,此处未显示)。
我得到编译器错误
cannot infer an appropriate lifetime due to conflicting requirements
expected `(&&Vec<&Inner>, &mut ThreadRng)`
found `(&&Vec<&Inner>, &mut ThreadRng)`
but, the lifetime must be valid for the static lifetime...
expected `Box<(dyn FnMut() -> Outer + 'static)>`
found `Box<dyn FnMut() -> Outer>`
我很困惑为什么输出Outer 必须具有静态生命周期。我正在创建一次Outer,使用全资拥有的Inner(克隆后),从匿名函数中返回它,并且不再在该匿名函数中使用它。我希望调用者 (let choice = get_choice()) 拥有对 Outer 的所有权。
This 问题有相同的错误但有所不同,因为在我的示例中,Outer 需要拥有 Inner。
我可以将策略定义更改为
type Strategy<'a> = Box<dyn Fn(&'a Vec<&'a Inner>) -> Box<dyn FnMut() -> Outer>>;
然后我得到错误
`inners` does not live long enough
borrowed value does not live long enoughrustcE0597
main.rs(38, 1): `inners` dropped here while still borrowed
main.rs(18, 26): type annotation requires that `inners` is borrowed for `'static`
(第38行是main函数的结尾)
每次我想使用策略时,如果不克隆整个内部,我不确定如何解决这个问题。
【问题讨论】: