2016-12-01 7 views
0

私は、参照によって突然変異させることができる形質の値を得ようとしています。アーク<RwLock>を&mutに変換する

trait MyTrait { 
    fn name<'a>(&'a mut self) -> &'a mut String; 
} 

struct SimpleImpl { 
    name: String 
} 

impl MyTrait for SimpleImpl { 
    fn name<'a>(&'a mut self) -> &'a mut String { 
     &mut self.name 
    } 
} 

use std::sync::{Arc,RwLock}; 

struct ParallelImpl { 
    name: Arc<RwLock<String>> 
} 

impl MyTrait for ParallelImpl { 
    fn name<'a>(&'a mut self) -> &'a mut String { 
     self.name.get_mut().unwrap() 
    } 
} 

fn main() { 
    let mut a = SimpleImpl { name: String::from("simple") }; 
    let mut b = ParallelImpl { name: Arc::new(RwLock::new(String::from("parallel"))) }; 

    a.name().as_mut_str(); 
    b.name().as_mut_str(); 
} 

これは

main2.rs:23:9: 23:18 error: cannot borrow immutable borrowed content as mutable 
main2.rs:23   self.name.get_mut().unwrap() 

なぜできないとコンパイルに失敗します。問題はString値が非常に大きく、私の解決策は、次のようになりますので、多くのスレッドによってアクセスすることができるということです電話番号get_mut()に電話してArcRwLockの両方をアンラップしますか?

+0

これは['owning_ref'](https://kimundi.github.io/owning-ref-rs/owning_ref/index.html)の別の仕事のようです。クレート。それは参照とよく似ているがガードを保持している['RwLockWriteGuardRef'](https://kimundi.github.io/owning-ref-rs/owning_ref/type.RwLockWriteGuardRef.html)タイプを含んでいます。 –

答えて

5

RwLockのインターフェイスをよく見てください。

get_mutは、ガードオブジェクトであるLockResult<&mut T>を返します。このガードが破壊されると、自動的にロックが解除されます。安全のために物事ためには、あなたはガードの上unwrap()を呼び出すことによって取得&mut Tがガードから借入である、つまり、unwrap()の結果の有効期間は、ガードのそれによって制限されている

(以降ガードが破壊された後、ロックは解除される)。参照の寿命は機能のものを超えることはできませんので、あなたは、一時的なガードを作成し、すぐにそれを離れて投げている

そして、ここでは、...

Congratz錆に!さらに別のデータ競合がコンパイル時に防止されました:)

+0

'name()'から 'LockResult <&mut T>'を返さなければなりませんか? –

+0

@ JohnMcCrae [これらの行](http://stackoverflow.com/a/40853817/1600898)に沿ってAPIを設計することもできます。そうすれば、パラレルと非パラレルの同じインタフェースが可能になります。 – user4815162342

+0

@ JohnMcCrae:もう少し複雑です。 Rustが、関連する型を生涯にわたってパラメータ化する機能を実装するまで、残念ながら、異なる型の特性から「Self」を借りるさまざまな型を返すことは不可能です... –

関連する問題