2016-10-29 1 views
1

eine Struktur gegeben, die einen Zeiger Wraps,Wie deklariere ich einen generischen Typ, der ein roher Zeiger ist?

pub struct Ptr<T> { 
    ptr: T 
} 

Ist es möglich, zu erklären, dass T ein Rohzeiger Typ sein muss? zB *mut SomeStruct oder *const SomeStruct.

Ohne dies kann ich Operationen wie &*self.ptr innerhalb einer Methode nicht ausführen, da Rust nicht ptr wie ein Zeiger behandelt werden kann.


Beachten Sie, dass dies gemacht werden kann, arbeiten:

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

Aber in diesem Fall ist es schwer Codes *mut, wo wir *const in anderen Fällen wollen könnten.

Siehe: this answer um etwas Kontext zu geben.

+1

Rohe Zeiger verwenden nicht 'ops :: Deref'. Es scheint, dass die Fähigkeit, einen Zeiger unsicher zu entfernen, irgendwie compilerintern ist. Es ist also nicht möglich, dieses unsichere Unwrap-Verhalten in einem generischen Kontext zu erhalten. Sie könnten ein benutzerdefiniertes Merkmal schreiben und eine eigene Methode zum Entfernen verwenden, anstatt den Operator zu verwenden ... –

+1

Ich denke, 'ptr' als Zeiger zu deklarieren ist der richtige Weg. Sie können immer zwischen '* const T' und' * mut T' mit 'as' konvertieren. Und wenn Sie wirklich eine Unterscheidung wollen, können Sie eine Enum mit zwei Varianten oder eine Eigenschaft mit zwei Strukturen, die es implementieren. –

Antwort

2

Ich bin nicht überzeugt, dass dies wert ist, getan, aber wenn Sie sicher sind, dann können Sie nur eine Eigenschaft schreiben:

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 } 
} 

Sie können dann P: RawPtr erfordern, wenn Funktionen der Umsetzung:

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() 
    } 
} 

Darüber hinaus ist es möglich, Methoden zu definieren, die nur verfügbar sind, wenn P ein veränderbarer Zeiger ist:

impl<T> Ptr<*mut T> { 
    unsafe fn get_mut(&mut self) -> *mut T { 
     self.ptr 
    } 
} 
Verwandte Themen