有关Rust寿命的问题 [英] Questions about Rust lifetime
问题描述
我正在尝试基于TypedArena
实现一个内存池.这是我原始代码的简化版本:
I'm trying to implement a memory pool based on TypedArena
. Here's a simplified version of my original code:
#![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);
:
However, the compiler complains about the line: 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
.
Why
data
does not have lifetime'a
? I'm thinking that sincepool
has lifetimea
andconsume
returns the same lifetime asself
, it should have lifetime'a
.
使此代码按预期工作的最佳方法是什么?基本上,我想分配新字节并将其寿命调整为与内存池相同.我知道我可以直接使用TypedArena
,因为alloc
不需要mut
引用.但是我真的想跟踪其他信息,例如bytes_allocated
.
What's the best way to make this code work as intended? Basically I want to allocate new bytes and adjust their lifetime to be the same as the memory pool. I know I can use TypedArena
directly since alloc
does not take a mut
reference. However I really want to track other information such as bytes_allocated
.
推荐答案
让我们逐步解决这个问题:
Let's tackle this step by step:
cannot infer an appropriate lifetime for autoref
"autoref"描述了为方法的self
自变量构建正确引用的过程.编译器无法找到具有正确生命周期的引用来调用consume()
.为什么不能呢?
"autoref" describes the process of building the right reference for the self
argument of a method. The compiler is unable to find a reference with the right lifetime to call consume()
. Why is it unable?
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);
| ^^^^^^^^^
匿名生存期#1"是指&mut self
的生存期.该注释只是在说:我们不能将寿命大于self
的生存期传递给consume()
:那么consume()
会认为其self
自变量的生存期比实际寿命更长.>
The "anonymous lifetime #1" refers to the lifetime of &mut self
. This note is just saying: we can't pass a reference with a lifetime greater than the lifetime of self
into consume()
: then consume()
would think that its self
argument lives longer than it actually does.
note: but, the lifetime must be valid for the lifetime 'a
这是您已经预期要应用的规则.但是现在问题出在哪里呢?好吧:&mut self
的生存期(匿名生命周期#1)可能比'a
生存期短 !就这样!而且我们可以很容易地解决它:
This is the rule you already expected to be applied. But where is the problem now? Well: the lifetime of &mut self
(anonymous lifetime #1) could life shorter than 'a
! That's all! And we can fix it quite easily:
impl<'a> S<'a> {
pub fn write<'b: 'a>(&'b mut self, buffer: &mut ByteArray<'a>) {
// ^^^^^^^^ ^^
...
}
}
在这里,我们仅将先前的匿名生存期命名为#1以便绑定它,说它必须 outlive 'a
(生存期长于'a
).
Here we just name the previously anonymous lifetime #1 to be able to bound it, saying that it has to outlive 'a
(live longer than 'a
).
这篇关于有关Rust寿命的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!