2016-08-20 4 views
1
use std::marker; 
use std::ops; 
pub struct Shared<'r, T: 'r> { 
    data: *mut T, 
    _pd: marker::PhantomData<&'r T>, 
} 

impl<'r, T> Shared<'r, T> { 
    pub fn new(value: T) -> Shared<'r, T> { 
     let boxed = Box::new(value); 
     Shared { 
      data: Box::into_raw(boxed), 
      _pd: marker::PhantomData, 
     } 
    } 

    pub fn as_ref(&self) -> SharedRef<'r, T> { 
     SharedRef { 
      data: self.data, 
      _pd: marker::PhantomData, 
     } 
    } 
} 

impl<'r, T> ops::Deref for Shared<'r, T> { 
    type Target = T; 
    fn deref(&self) -> &T { 
     unsafe { &*self.data } 
    } 
} 

pub struct SharedRef<'r, T: 'r> { 
    data: *mut T, 
    _pd: marker::PhantomData<&'r T>, 
} 

impl<'r, T> ops::Deref for SharedRef<'r, T> { 
    type Target = T; 
    fn deref(&self) -> &T { 
     unsafe { &*self.data } 
    } 
} 

impl<'r, T> Drop for Shared<'r, T> { 
    fn drop(&mut self) { 
     unsafe { 
      Box::from_raw(self.data); 
     } 
    } 
} 

fn main() { 
    let s = Shared::new(42); 
    let s_ref = s.as_ref(); 
    { 
     let s1 = s; 
    } 
    // lifetime should end here 
    println!("{}", *s_ref); 
} 

私が表現したかったのは、BoxArcです。参照を与えることができる一意に所有されたポインタ。不変の借用でも移動できますか?

現在、不変の借用がある場合でも、Sharedを移動できるようにしたいという問題があります。このシナリオでは、ヒープ割り当てされているので、合法である必要があります。

問題は、これを表現する方法がわかりません。

fn main() { 
    let s = Shared::new(42); 
    let s_ref = s.as_ref(); 
    { 
     let s1 = s; 
    } 
    // lifetime should end here 
    println!("{}", *s_ref); 
} 

は、ここで私はそれを前に持っていたよりも「少ない」寿命のスコープにsを移動します。しかし、今度はss1に移動した後、もうs_refにアクセスできないようにしてください。だから私が言いたいのは、生涯がより小さくならないならばSharedを動かすことは大丈夫だということです。

これは錆で表現できますか?

+0

あなたは[owning-ref](https://github.com/Kimundi/owning-ref-rs)を見ましたか? – Shepmaster

+0

'Shared'の' PhantomData'は正しく見えません。 'Shared' *はそのアイテムを所有しています。 –

+0

@Shepmaster私はそれが私を助けるかどうかはわかりません。私はここでより具体的な質問をしましたhttp://stackoverflow.com/questions/39079922/is-it-possible-to-have-internal-pointers-without-using-an-arc –

答えて

1

錆はあなたがSharedの外に移動することを可能にする理由は、あなたがそれに戻っSharedRefの寿命を縛られていないことである。

pub fn as_ref(&self) -> SharedRef<'r, T> { 
    SharedRef { 
     data: self.data, 
     _pd: marker::PhantomData, 
    } 
} 

注釈を付ける&self修正される:

pub fn as_ref(&'r self) -> SharedRef<'r, T> { .. } 

現在の主な違いは、SharedRefの有効期間がの有効期間と一致していることです。が0123です、生き残りを維持する。実際には、Sharedと同じ生涯('r)である必要はありません。

pub fn as_ref<'b>(&'b self) -> SharedRef<'b, T> { .. } 

これは移動を許可しません。

質問のボーナス部分については、生涯が十分に長い限り、移動を許可したいところでは、答えはノーと思います。私が何かを動かすのを止めるために知っている唯一の方法は、それを借りることです。

関連する問題