方便访问原始指针成员吗? [英] Convenient access to members of raw pointers?

查看:28
本文介绍了方便访问原始指针成员吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于我们知道不需要检查 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆