从对象池中借用时解决省略的静态生命周期
Resolve elided static lifetime when borrowing from an object pool
这是我目前面临的问题的简化版本。
trait SuperObject {
fn object_name(&self) -> String;
}
trait Inspect {
fn inspect(&self);
}
impl Inspect for SuperObject {
fn inspect(&self) {
println!("I am a Superobject.");
}
}
struct Object {
name: String
}
impl SuperObject for Box<Object> {
fn object_name(&self) -> String {
format!("I am {}.", self.name.clone())
}
}
struct ObjectPool {
object1: Box<Object>,
object2: Box<Object>,
object3: Box<Object>
}
impl ObjectPool {
pub fn new() -> ObjectPool {
ObjectPool {
object1: Box::new(Object { name: String::from("Object 1") }),
object2: Box::new(Object { name: String::from("Object 2") }),
object3: Box::new(Object { name: String::from("Object 3") })
}
}
fn all_objects(&self) -> Vec<&SuperObject> {
let mut ret: Vec<&SuperObject> = Vec::new();
ret.push(&self.object1);
ret.push(&self.object2);
ret.push(&self.object3);
ret
}
}
fn main() {
let objectpool: ObjectPool = ObjectPool::new();
let allobjects: Vec<&SuperObject> = objectpool.all_objects();
for i in &allobjects {
println!("{}", i.object_name());
// Comment the following line in order to drop error E0597
i.inspect(); // FIXME: borrowed value must be valid for the static lifetime
}
}
尝试编译此代码段时出现如下错误:
error[E0597]: `objectpool` does not live long enough
--> src/main.rs:50:41
|
50 | let allobjects: Vec<&SuperObject> = objectpool.all_objects();
| ^^^^^^^^^^ does not live long enough
...
56 | }
| - borrowed value only lives until here
|
= note: borrowed value must be valid for the static lifetime...
error: aborting due to previous error
经过多次搜索,据我了解,被实例化的对象具有默认的静态生命周期,如https://doc.rust-lang.org/book/second-edition/ch19-02-advanced-lifetimes.html
中所述
我相信 ObjectPool 的 all_objects 方法的输出被编译器忽略为静态的,正如我尝试调试代码片段时引发的错误之一所证明的那样:
error[E0308]: mismatched types
--> src/main.rs:42:18
|
42 | ret.push(&self.object2);
| ^^^^^^^^^^^^^ expected struct `std::boxed::Box`, found reference
|
= note: expected type `std::boxed::Box<SuperObject>`
found type `&std::boxed::Box<SuperObject + 'static>`
不涉及完全废弃对象池的最佳行动方案是什么?或者是否有适合 Rust 实现的更优雅的抽象?
问题出在您的 impl Inspect for SuperObject
上。为另一个特征实现一个特征 而不是 做你期望的事情。基本上规则是:永远不要这样做。从本质上讲,这意味着只有当您拥有 &(SuperObject + 'static)
时,您才能将其视为 Inspect
。你要的是
impl<T: SuperObject + ?Sized> Inspect for T {
fn inspect(&self) {
println!("I am a Superobject.");
}
}
这是我目前面临的问题的简化版本。
trait SuperObject {
fn object_name(&self) -> String;
}
trait Inspect {
fn inspect(&self);
}
impl Inspect for SuperObject {
fn inspect(&self) {
println!("I am a Superobject.");
}
}
struct Object {
name: String
}
impl SuperObject for Box<Object> {
fn object_name(&self) -> String {
format!("I am {}.", self.name.clone())
}
}
struct ObjectPool {
object1: Box<Object>,
object2: Box<Object>,
object3: Box<Object>
}
impl ObjectPool {
pub fn new() -> ObjectPool {
ObjectPool {
object1: Box::new(Object { name: String::from("Object 1") }),
object2: Box::new(Object { name: String::from("Object 2") }),
object3: Box::new(Object { name: String::from("Object 3") })
}
}
fn all_objects(&self) -> Vec<&SuperObject> {
let mut ret: Vec<&SuperObject> = Vec::new();
ret.push(&self.object1);
ret.push(&self.object2);
ret.push(&self.object3);
ret
}
}
fn main() {
let objectpool: ObjectPool = ObjectPool::new();
let allobjects: Vec<&SuperObject> = objectpool.all_objects();
for i in &allobjects {
println!("{}", i.object_name());
// Comment the following line in order to drop error E0597
i.inspect(); // FIXME: borrowed value must be valid for the static lifetime
}
}
尝试编译此代码段时出现如下错误:
error[E0597]: `objectpool` does not live long enough
--> src/main.rs:50:41
|
50 | let allobjects: Vec<&SuperObject> = objectpool.all_objects();
| ^^^^^^^^^^ does not live long enough
...
56 | }
| - borrowed value only lives until here
|
= note: borrowed value must be valid for the static lifetime...
error: aborting due to previous error
经过多次搜索,据我了解,被实例化的对象具有默认的静态生命周期,如https://doc.rust-lang.org/book/second-edition/ch19-02-advanced-lifetimes.html
中所述我相信 ObjectPool 的 all_objects 方法的输出被编译器忽略为静态的,正如我尝试调试代码片段时引发的错误之一所证明的那样:
error[E0308]: mismatched types
--> src/main.rs:42:18
|
42 | ret.push(&self.object2);
| ^^^^^^^^^^^^^ expected struct `std::boxed::Box`, found reference
|
= note: expected type `std::boxed::Box<SuperObject>`
found type `&std::boxed::Box<SuperObject + 'static>`
不涉及完全废弃对象池的最佳行动方案是什么?或者是否有适合 Rust 实现的更优雅的抽象?
问题出在您的 impl Inspect for SuperObject
上。为另一个特征实现一个特征 而不是 做你期望的事情。基本上规则是:永远不要这样做。从本质上讲,这意味着只有当您拥有 &(SuperObject + 'static)
时,您才能将其视为 Inspect
。你要的是
impl<T: SuperObject + ?Sized> Inspect for T {
fn inspect(&self) {
println!("I am a Superobject.");
}
}