Rust 无法定义适当的防锈寿命要求
TL;博士 嵌套对象的生存期有问题。代码如下 长版本: 我正在使用Rust 无法定义适当的防锈寿命要求,rust,traits,lifetime,Rust,Traits,Lifetime,TL;博士 嵌套对象的生存期有问题。代码如下 长版本: 我正在使用ggez编写一个多人游戏,并尝试为输入创建一个抽象层(允许本地和远程玩家一起玩) 为此,我创建了一个Inputtrait,并为本地输入实现了KeyboardInput,它使用ggez键盘状态查询方法 现在棘手的部分是:ggez在启动时创建Context对象,并期望在大多数公开的函数中引用它 因为我的KeyboardInput实现使用的是ggez输入法(具体地说,是按下键的),所以它必须将&Context传递给此方法。但是,由于tr
ggez
编写一个多人游戏,并尝试为输入创建一个抽象层(允许本地和远程玩家一起玩)
为此,我创建了一个Input
trait,并为本地输入实现了KeyboardInput
,它使用ggez
键盘状态查询方法
现在棘手的部分是:ggez
在启动时创建Context
对象,并期望在大多数公开的函数中引用它
因为我的KeyboardInput
实现使用的是ggez
输入法(具体地说,是按下键的
),所以它必须将&Context
传递给此方法。但是,由于trait本身应该是泛型的,因此任何其他实现(例如,NetworkInput
)都不需要Context
引用
我的解决方案是在键盘输入
结构中添加对上下文
as字段的引用。然而,这导致了一个终生的错误,我仍然无法解决
我还尝试将生存期设置为静态的
,但这也不起作用
以下是相关代码:
pub trait Input {
fn get_direction(&self) -> Direction;
}
pub struct KeyboardInput<'a> {
left_key: KeyCode,
right_key: KeyCode,
_ctx: &'a Context
}
impl KeyboardInput<'_> {
pub fn new(_ctx: &Context, left_key: KeyCode, right_key: KeyCode) -> KeyboardInput {
KeyboardInput{
_ctx,
left_key,
right_key
}
}
}
impl Input for KeyboardInput<'_> {
fn get_direction(&self) -> Direction {
if ggez::input::keyboard::is_key_pressed(self._ctx, self.left_key) {
return Direction::Left;
}
if ggez::input::keyboard::is_key_pressed(self._ctx, self.right_key) {
return Direction::Right;
}
Direction::Unchanged
}
}
struct Player {
angle: f32,
pos_x: f32,
pos_y: f32,
input_manager: Box<dyn Input>,
}
impl <'a>MainState {
fn new(ctx: &'a Context) -> GameResult<MainState> {
let kbd_input = KeyboardInput::new(ctx, KeyCode::Left, KeyCode::Right);
let kbd_input = Box::new(kbd_input);
let s = MainState {
last_update: Instant::now(),
players: vec![
Player::new(kbd_input)
]
};
Ok(s)
}
}
pub fn main() -> GameResult {
let cb = ggez::ContextBuilder::new("My game", "ggez");
let (ctx, event_loop) = &mut cb.build()?;
let state = &mut MainState::new(&ctx)?;
event::run(ctx, event_loop, state)
}
pub特征输入{
fn获取方向(&self)->方向;
}
pub结构键盘输入{
fn获取方向(&self)->方向{
如果按了键盘::键(self.\u ctx,self.left\u键){
返回方向:左;
}
如果按了键盘::键(self.\u ctx,self.right\u键){
返回方向:右;
}
方向:不变
}
}
结构播放器{
角度:f32,
位置x:f32,
位置y:f32,
输入管理器:框,
}
impl游戏结果{
让kbd_input=KeyboardInput::new(ctx,KeyCode::Left,KeyCode::Right);
让kbd_input=Box::new(kbd_input);
设s=MainState{
上次更新:Instant::now(),
玩家:维克[
播放器::新建(kbd_输入)
]
};
好(s)
}
}
pub fn main()->GameResult{
让cb=ggez::ContextBuilder::new(“我的游戏”、“ggez”);
let(ctx,event_loop)=&mut cb.build()?;
let state=&mut MainState::new(&ctx)?;
事件::运行(ctx、事件循环、状态)
}
和编译器错误:
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> src\main.rs:75:25
|
75 | let kbd_input = KeyboardInput::new(ctx, KeyCode::Left, KeyCode::Right);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the impl at 72:7...
--> src\main.rs:72:7
|
72 | impl <'a>MainState {
| ^^
note: ...so that reference does not outlive borrowed content
--> src\main.rs:75:44
|
75 | let kbd_input = KeyboardInput::new(ctx, KeyCode::Left, KeyCode::Right);
| ^^^
= note: but, the lifetime must be valid for the static lifetime...
= note: ...so that the expression is assignable:
expected std::boxed::Box<(dyn input_manager::Input + 'static)>
found std::boxed::Box<dyn input_manager::Input>
error[E0495]:由于需求冲突,无法为函数调用中的生存期参数推断适当的生存期
-->src\main.rs:75:25
|
75 |让kbd|U输入=键盘输入::新建(ctx,键码::左,键码::右);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
注意:首先,生命周期不能超过impl上72:7定义的生命周期“a”。。。
-->src\main.rs:72:7
|
72 | impl
找到std::boxed::Box
此错误几乎总是意味着您试图以一种方式存储一个值,使其存在时间超过其生命周期
让我们看一段特定的代码,用显式类型和生命周期进行注释:
impl游戏结果{
让kbd_输入:键盘输入=框::新(kbd_输入);
让我们:主流=主流{
上次更新:Instant::now(),
玩家:维克[
Player::new(kbd_输入为Box
。这将级联并意味着您还需要向主状态
结构添加生存期,因为它现在将包含一个具有非静态生存期的类型:
struct-MainState>,
}
此错误几乎总是意味着您试图以一种方式存储一个值,使其存在时间超过其生命周期
让我们看一段特定的代码,用显式类型和生命周期进行注释:
impl游戏结果{
让kbd_输入:键盘输入=框::新(kbd_输入);
让我们:主流=主流{
上次更新:Instant::now(),
玩家:维克[
Player::new(kbd_输入为Box
。这将级联并意味着您还需要向主状态
结构添加生存期,因为它现在将包含一个具有非静态生存期的类型:
struct-MainState>,
}