我在玩小游戏时遇到了一生的问题。以下代码表示更新循环的简化版本。 我需要容器可变引用来获取对其他游戏对象的引用,或者创建新的对象或触发功能。
由于这个原因,我需要 v = choice[I](n);
特性才能将其转换为结构,因此在我的Any
特性中,我添加了一个GameObj
方法,但这导致一生的问题。
as_any
当我尝试构建代码时,它导致以下错误消息。
如果我在use std::any::Any;
trait GameObj<'a> {
fn as_any<'b>(&'b self) -> &'b (dyn Any + 'a);
fn update(&mut self, cont: &mut container);
}
struct object<'a> {
content: &'a String,
}
impl<'a> GameObj<'a> for object<'a> {
fn as_any<'b>(&'b self) -> &'b (dyn Any + 'a) {
return self;
}
fn update(&mut self, cont: &mut container) {
let val = cont.get_obj().unwrap();
let any = val.as_any();
}
}
struct container<'a> {
data: Vec<Box<dyn GameObj<'a> + 'a>>,
}
impl<'a> container<'a> {
fn get_obj<'b>(&'b self) -> Option<&'b Box<dyn GameObj<'a> + 'a>> {
return Some(&self.data[0]);
}
}
pub fn main() {
let a = String::from("hallo");
let b = String::from("asdf");
{
let abc = object { content: &a };
let def = object { content: &b };
let mut cont = container { data: Vec::new() };
cont.data.push(Box::new(abc));
cont.data.push(Box::new(def));
loop {
for i in 0..cont.data.len() {
let mut obj = cont.data.remove(0);
obj.update(&mut cont);
cont.data.insert(i, obj);
}
}
}
}
函数中注释/删除了let any = val.as_any();
,则可以正常编译。
update
在不使用error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
--> src/main.rs:18:24
|
18 | let val = cont.get_obj().unwrap();
| ^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #3 defined on the method body at 17:5...
--> src/main.rs:17:5
|
17 | / fn update(&mut self, cont: &mut container) {
18 | | let val = cont.get_obj().unwrap();
19 | | let any = val.as_any();
20 | | }
| |_____^
= note: ...so that the types are compatible:
expected &container<'_>
found &container<'_>
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that the declared lifetime parameter bounds are satisfied
--> src/main.rs:19:23
|
19 | let any = val.as_any();
| ^^^^^^
的情况下如何进行这项工作,或者为什么这不可能呢?
答案 0 :(得分:1)
Any
是declared trait Any: 'static
,可以only store 'static
types。因此,为了使dyn Any + 'a
成为格式正确的类型,您的as_any
方法被赋予了隐式的'a: 'static
边界,从而导致了所显示的生命周期错误。
如果没有此限制,则可以通过将'a
类型放入Any
并排除'static
类型来破坏安全性,因为TypeId
无法分辨差异-编译期间会删除生命。有关更多信息,请参见discussion on RFC 1849。
您应该更仔细地考虑为什么要使用Any
。这几乎从来不是您真正想要的。也许像您想存储的所有不同对象类型的enum
类型那样简单,就可以更好地满足您的用例?
如果您确实要使用Any
,则需要找到一种使您的类型为'static
的方法。 Rc
(如果涉及线程,则为Arc
)通常有助于实现此目的;例如,您可以将object
的商店Rc<String>
(或更好的Rc<str>
)而不是&'a String
。