方便访问原始指针成员吗? [英] Convenient access to members of raw pointers?
问题描述
对于我们知道不需要检查 NULL 的实例,访问原始指针的嵌套成员的表示法可能相当笨拙:
The notation for accessing nested members of raw pointers for instances we know don't need to be checked against NULL can be rather awkward:
struct MyLink {
link: *mut MyLink,
}
let var = *(*(*(*root).link).link).link;
可以访问原始指针的结构成员而不必每次都显式取消引用吗?也许通过使用诸如 root.link().link().link()
之类的方法或通过包装类型?
Can raw pointer's struct members be accessed without having to explicitly de-reference each time? Maybe by using methods like root.link().link().link()
or by wrapping the type?
虽然惯用的 Rust 避免了这种情况,但也有一些特殊情况不太容易避免.Rc
有内存开销,借用检查器导致互连成员出现问题,C-API 可能需要指针......等.
While idiomatic Rust avoids this, there are exceptional cases where it isn't so easy to avoid. Rc
has memory overhead, borrow checker causes problems for inter-linking members, C-API may require pointers... etc.
推荐答案
如果这在您的代码中反复出现,我会创建一个通用包装器.
If this is a recurring situation in your code, I'd just create a generic wrapper.
#[repr(C)]
#[derive(Hash)]
struct Ptr<T> {
ptr: *mut T
}
impl<T> Ptr<T> {
pub unsafe fn new(ptr: *mut T) -> Ptr<T> {
debug_assert!(!ptr.is_null());
Ptr { ptr: ptr }
}
#[inline(always)]
pub fn as_pointer(&self) -> *mut T {
self.ptr
}
}
impl<T> Deref for Ptr<T> {
type Target = T;
#[inline(always)]
fn deref(&self) -> &T {
unsafe { &*self.ptr }
}
}
impl<T> DerefMut for Ptr<T> {
#[inline(always)]
fn deref_mut(&mut self) -> &mut T {
unsafe { &mut *self.ptr }
}
}
impl<T> Copy for Ptr<T> { }
impl<T> Clone for Ptr<T> {
#[inline(always)]
fn clone(&self) -> Ptr<T> { *self }
}
impl<T> PartialEq for Ptr<T> {
fn eq(&self, other: &Ptr<T>) -> bool {
self.ptr == other.ptr
}
}
我们在构造时断言 ptr
实际上不为 null,因此在取消引用时我们不必再次检查.
We assert upon construction that the ptr
is effectively not null, so we do not have to check again when dereferencing.
然后我们让语言在调用方法或访问属性时检查Deref
/DerefMut
:
Then we let the language check for Deref
/DerefMut
when calling a method or accessing an attribute:
struct MyLink {
link: Ptr<MyLink>,
}
fn main() {
let mut link = MyLink { link: unsafe { Ptr::new(1 as *mut _) } };
let next = MyLink { link: unsafe { Ptr::new(&mut link as *mut _) } };
let _ = next.link;
}
这篇关于方便访问原始指针成员吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!