【发布时间】:2018-02-04 13:17:16
【问题描述】:
归结起来的问题如下:
use std::marker::PhantomData;
struct WorldState<'a> {
state: &'a f64,
}
trait CalculateWorldState<T> {
fn state_value(&mut self, input: &T) -> f64;
}
trait LearningAlgorithm<T> {
fn print_learning_information(&self, &T);
}
struct EvolutionaryAlgorithm<F, T>
where
F: CalculateWorldState<T>,
{
//I need this since I only use T as a method parameter, I do not save it anywhere
//T are different ways to represent the current worldstate and are
//short-lived (new ones generated every frame)
_p_: PhantomData<T>,
//I don't actually need this one in the real example since I have
//an instatiated version of type CalculateWorldState saved in the
//struct but I use phantomdata for simplicity of the example
_p: PhantomData<F>,
}
impl<F, T> LearningAlgorithm<T> for EvolutionaryAlgorithm<F, T>
where
F: CalculateWorldState<T>,
{
fn print_learning_information(&self, input: &T) {
println!("My learning goes splendid!");
//do something with &T by calling the object of type
//CalculateWorldState which we have saved somewhere, but do
//not save the &T reference anywhere, just look at it
}
}
struct WorldIsInGoodState {}
impl<'a> CalculateWorldState<WorldState<'a>> for WorldIsInGoodState {
fn state_value(&mut self, input: &WorldState) -> f64 {
100.
}
}
fn main() {
let mut a: Box<LearningAlgorithm<WorldState>> =
Box::new(EvolutionaryAlgorithm::<WorldIsInGoodState, WorldState> {
_p: PhantomData,
_p_: PhantomData,
});
{
let state = WorldState { state: &5. };
a.print_learning_information(&state);
}
}
以上代码编译失败:
error[E0597]: borrowed value does not live long enough
--> src/main.rs:59:5
|
57 | let state = WorldState { state: &5. };
| -- temporary value created here
58 | a.print_learning_information(&state);
59 | }
| ^ temporary value dropped here while still borrowed
60 | }
| - temporary value needs to live until here
WorldState<'a> 是一种寿命很短的数据类型(每帧一个),而LearningAlgorithm 是一种寿命很长的数据类型(多个游戏)。但是我实现这件事的方式,Rust 急切地相信,我传递给 print_learning_information 的每个 WorldState 都必须比 LearningAlgorithm 寿命长。
我做错了什么?不然怎么处理?
一些我不想做的事情:
- 让
WorldState包含一个正常状态(因为实际上它包含一些向量而不是f64,我不想在传递每个玩家自己的视图时将它们复制到WorldState结构中世界) - 干脆退出这个项目并开始一个新项目(大家都知道,投入一些时间后,你不会想把所有的工作都扔掉)
【问题讨论】:
-
问题似乎是暂时的。为什么不在第 60 行结束的范围内定义一个 var?
let wstate = 5.;之类的东西你的真实状态更复杂,所以可能已经存在了。 -
问题是,内部范围实际上是游戏循环。我也许可以将状态作为我的游戏对象的变量,以便它在整个游戏中存活下来,我只是改变它。但是学习算法甚至可以在多个游戏中存活下来,我无法让游戏状态在所有游戏中都成为全局变量,因为唯一能活这么久的对象是学习算法,游戏对象是为每个游戏新创建的
-
您的示例适用于夜间 Rust。我还不确定哪些更改使它可以编译。
-
啊,那是PR 43838。在一般情况下它不会有帮助。
标签: rust lifetime ownership-semantics