2016-12-01 1 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 값이 매우 크고 많은 스레드가 액세스 할 수 있으므로 내 솔루션을 이런 식으로 뭔가를 보이는 것입니다 으로 전화하여 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'를 빌려 오는 여러 유형을 반환하는 것은 유감 스럽지만 불가능합니다 ... –