2016-10-29 12 views
1
ポインタをラップ構造体を考えると

生のポインタであるジェネリック型を宣言するには?

pub struct Ptr<T> { 
    ptr: T 
} 

はそれがTは、生のポインタ型でなければならないことを宣言することは可能ですか?例えば*mut SomeStructまたは*const SomeStructです。

これがなければ、方法の中で&*self.ptrのような操作を実行することができません。なぜなら、Rustはptrをポインタのように扱うことができないということを知らないからです。


これを動作させることができることに注意してください:我々は、他の例で*constをお勧めします

pub struct Ptr<T> { 
    ptr: *mut T 
} 

しかし、その場合には、そのハードコード*mut、。

参照:this answerいくつかの文脈を与える。

+1

生ポインタは 'ops :: Deref'を使用しません。 unsafeなポインタをderefする能力は、何らかの形でコンパイラ内部にあるようです。だから私はそれが一般的なコンテキストでこの安全ではない展開の動作を得ることは不可能だと思います。あなたはカスタム特性を書いて、演算子を使う代わりにderefに独自のメソッドを使うことができます。 –

+1

ポインタとして 'ptr'を宣言するのが正しい方法だと思います。 '* const T 'と' * mut T'の間はいつでも 'as'を使って変換できます。また、実際に区別が必要な場合は、2つのバリアントを持つ列挙型またはそれを実装する2つの構造体を持つ特性を使用できます。 –

答えて

2

私はこれがやって価値がある確信していないが、あなたは確信しているならば、あなただけの形質を書き込むことができます。

pub trait RawPtr: Sized { 
    type Value; 

    fn as_const(self) -> *const Self::Value { 
     self.as_mut() as *const _ 
    } 

    fn as_mut(self) -> *mut Self::Value { 
     self.as_const() as *mut _ 
    } 
} 

impl<T> RawPtr for *const T { 
    type Value = T; 
    fn as_const(self) -> Self { self } 
} 

impl<T> RawPtr for *mut T { 
    type Value = T; 
    fn as_mut(self) -> Self { self } 
} 

あなたのできる機能を実装するときにP: RawPtrが必要になります。

pub struct Ptr<P> { 
    ptr: P 
} 

impl<P: RawPtr> Ptr<P> { 
    unsafe fn get(self) -> P::Value 
     where P::Value: Copy 
    { 
     *self.ptr.as_const() 
    } 
} 

さらに、Pが可変ポインタである場合にのみ使用可能なメソッドを定義することができます。

impl<T> Ptr<*mut T> { 
    unsafe fn get_mut(&mut self) -> *mut T { 
     self.ptr 
    } 
} 
関連する問題