2015-10-27 4 views
5

私は、Vec<RefCell<T>>のようなクラスを探しています。それは究極のオーナー&のすべてのデータのアロケータですが、アレイのさまざまな部分を無期限に複数のパーティーから借用することができます。RefCellのようなより親しみやすいオブジェクトがありますか?

ため、私はまたmutably複数の当事者で借りることができVec<T>のコース個の無期限を強調するが、これは関係者が借りて行われた後にのみ解決できる分割を行うことが含まれます。

Vec<RefCell<T>>は、unstableと思われるの文をチェックすると、多くの醜いifステートメントのようです。あなたが何か間違っているなら、kablammo!パニック!これは貸出図書館のようなものではありません。貸出図書館では、そこにない本を尋ねると、「ああ、チェックアウトされました」と伝えます。誰も爆発で死ぬことはない。

だから私はこのようなコードに何か書きたいと思います:

let mut a = LendingLibrary::new(); 
a.push(Foo{x:10}); 
a.push(Foo{x:11}); 
let b1 = a.get(0); // <-- b1 is an Option<RefMut<Foo>> 
let b2 = a.get(1); // <-- b2 is an Option<RefMut<Foo>> 

// the 0th element has already been borrowed, so... 
let b3 = a.get(0); // <-- b3 is Option::None 

ようなものが存在していますか?あるいは、このような振る舞いを得るための別の標準的な方法がありますか?フレンドリーRefCellの一種?

答えが「はい」の場合は、スレッドセーフバリアントもありますか?

答えて

2

RefCellは、長寿命の借用用に設計されていません。典型的なユースケースは、ある関数では、RefCellを(可変または不変のいずれかで)借りて、その値で作業し、次に返す前に借りを解放するということです。シングルスレッドのコンテキストで借用したRefCellから回復する方法を知りたいと思っています。

RefCellに相当するスレッドセーフは、RwLockです。互換性のないロックがまだ取得されている場合(現在のスレッドを含むすべてのスレッドで)、ブロックされたりパニックにならない関数はtry_readtry_writeです。逆にRefCellとは逆に、RwLockのロックが失敗した場合には、後で再試行することは理にかなっています。

あなたは常にwriteまたはtry_write、決してreadまたはtry_readを使用して終了した場合、あなたはおそらく代わりにMutex単純なを使用する必要があります。

1
#![feature(borrow_state)] 
use std::cell::{RefCell, RefMut, BorrowState}; 

struct LendingLibrary<T> { 
    items: Vec<RefCell<T>> 
} 

impl<T> LendingLibrary<T> { 
    fn new(items: Vec<T>) -> LendingLibrary<T> { 
     LendingLibrary { 
      items: items.into_iter().map(|e| RefCell::new(e)).collect() 
     } 
    } 

    fn get(&self, item: usize) -> Option<RefMut<T>> { 
     self.items.get(item) 
      .and_then(|cell| match cell.borrow_state() { 
       BorrowState::Unused => Some(cell.borrow_mut()), 
       _ => None 
      }) 
    } 
} 

fn main() { 
    let lib = LendingLibrary::new(vec![1, 2, 3]); 

    let a = lib.get(0); // Some 
    let b = lib.get(1); // Some 

    let a2 = lib.get(0); // None 
} 

これは現在、夜​​間リリースが必要です。

関連する問題