2017-04-05 12 views
0

私は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); 
    |   ^^^^^^^^ 

私の質問は次のとおりです。ここに私の元のコードの簡易版です

  1. dataがない理由一生持ちました'apoolの有効期間はaで、consumeselfと同じ寿命を返しますので、寿命は'aである必要があります。

  2. このコードを意図したとおりに動作させるにはどうすればよいでしょうか?基本的には、新しいバイトを割り当てて、メモリプールと同じになるように寿命を調整したいと思います。私はallocmutの参照を取っていないので、TypedArenaを直接使用できることを知っています。しかし、私は本当にbytes_allocatedのような他の情報を追跡したい。

答えて

0

のステップにより、このステップに取り組むみましょう:

cannot infer an appropriate lifetime for autoref 

「AUTOREF」メソッドの引数selfための右基準を構築するプロセスを説明します。コンパイラは、consume()を呼び出すために正しい生存期間を持つ参照を見つけることができません。それはなぜできないのですか?

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引数が実際より長く存続すると考えています。

note: but, the lifetime must be valid for the lifetime 'a 

これはあなたが既に適用されることを期待しているルールです。しかし、今どこに問題がありますか?まあ、&mut self(匿名生涯#1)の生涯は、の寿命が短くなりましたより'a!それで全部です!そして、我々は非常に簡単にそれを修正することができます:

impl<'a> S<'a> { 
    pub fn write<'b: 'a>(&'b mut self, buffer: &mut ByteArray<'a>) { 
     //  ^^^^^^^^ ^^ 
     ... 
    } 
} 

をここでは単ににそれが持っていると言って、それをバインドできるようにする前に匿名の生涯#1に名前を付ける'aを(長い'aより生きる)より長生き。

+0

ありがとうございました。私は、私が持っていた混乱は、 'self.pool'が' pool'の代わりに 'self'の生涯を持ち、' ​​pool'が変更可能であるということでした。これは、プールに付けられた生涯の注釈 '' a''があるので直観的ではありません。コードを修正するために、 '' self'に '' b''を追加するのではなく、他の提案がありますか?構造体 'S'が' 'a'よりも短いと予想されるため、これは私の元のコードでは機能しません。 –

+0

@ChaoSunそれはできません。 'MemoryPool'はそれ自身よりも長い参照を返すことはできず、' S'はそれ自身よりも長いものを参照するものを返すことができず、 'S :: pool'は' S' 。私はあなたが達成しようとしていることをはっきりとは分かりません。 –

+0

説明をありがとう。私はこのことを再設計する必要があると思う。 –