我遇到了一个终生问题,一个小游戏。下面的代码表示的更新循环的非常归结版本。我需要的容器可变引用得到引用到其他游戏对象或创造新的或触发功能。
出于这个原因,我需要的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();
| ^^^^^^
我怎样才能使这项工作,而无需使用'static
,或者这是为什么不可能?
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
。