我試圖實現基於TypedArena
的內存池。下面是我的原代碼的簡化版本:關於鏽蝕壽命的問題
#![feature(rustc_private)]
extern crate arena;
use arena::TypedArena;
pub struct MemoryPool {
arena: TypedArena<Vec<u8>>,
bytes_allocated: usize,
}
impl MemoryPool {
pub fn consume(&mut self, buf: Vec<u8>) -> &[u8] {
self.bytes_allocated += buf.capacity();
self.arena.alloc(buf)
}
}
pub struct ByteArray<'a> {
data: &'a [u8],
}
impl<'a> ByteArray<'a> {
pub fn set_data(&mut self, data: &'a [u8]) {
self.data = data;
}
}
pub struct S<'a> {
pool: &'a mut MemoryPool,
}
impl<'a> S<'a> {
pub fn write(&mut self, buffer: &mut ByteArray<'a>) {
let v = vec!();
let data = self.pool.consume(v);
buffer.set_data(data);
}
}
然而,編譯器抱怨行:let data = self.pool.consume(v);
:
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> <anon>:34:26
|
34 | let data = self.pool.consume(v);
| ^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the body at 32:54...
--> <anon>:32:55
|
32 | pub fn write(&mut self, buffer: &mut ByteArray<'a>) {
| _______________________________________________________^ starting here...
33 | | let v = vec!();
34 | | let data = self.pool.consume(v);
35 | | buffer.set_data(data);
36 | | }
| |___^ ...ending here
note: ...so that reference does not outlive borrowed content
--> <anon>:34:16
|
34 | let data = self.pool.consume(v);
| ^^^^^^^^^
note: but, the lifetime must be valid for the lifetime 'a as defined on the body at 32:54...
--> <anon>:32:55
|
32 | pub fn write(&mut self, buffer: &mut ByteArray<'a>) {
| _______________________________________________________^ starting here...
33 | | let v = vec!();
34 | | let data = self.pool.consume(v);
35 | | buffer.set_data(data);
36 | | }
| |___^ ...ending here
note: ...so that types are compatible (expected &mut ByteArray<'_>, found &mut ByteArray<'a>)
--> <anon>:35:12
|
35 | buffer.set_data(data);
| ^^^^^^^^
我的問題是:
爲什麼
data
不有終身'a
?我在想,由於pool
的使用壽命爲a
,並且consume
的返回壽命與self
相同,因此應該有終生使用期限'a
。使代碼正常工作的最佳方式是什麼?基本上我想分配新的字節並將其生存期調整爲與內存池相同。我知道我可以直接使用
TypedArena
,因爲alloc
不需要mut
參考。不過,我真的想跟蹤其他信息,如bytes_allocated
。
謝謝。我認爲我的困惑是'self.pool'擁有'self'而不是'pool','pool'是可變的。這是不直觀的,因爲有一個生命週期註釋「a」附加到「池」。爲了修復代碼,你有其他建議,而不是爲'self'添加'b'嗎?這對我的原始代碼不起作用,因爲結構「S」預計比「a」短。 –
@ChaoSun這是不可能的。 'MemoryPool'不能返回一個比它自己壽命更長的引用,同樣,'S'不能返回引用的東西比它自己長,並且'S :: pool'的壽命與'S'一樣長。我不太清楚你想要達到的目標。 –
感謝您的解釋。我想我需要重新設計這個東西.. –