拥有一些数据和对数据的引用的结构 [英] Struct that owns some data and a reference to the data

查看:70
本文介绍了拥有一些数据和对数据的引用的结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对象的构造分配了该对象生命周期所需的数据,但也创建了另一个需要保留对数据的引用的对象:

Construction of an object allocates data needed for lifetime of that object, but also creates another object that needs to keep references to the data:

pub fn new() -> Obj {
    let data = compute();

    Obj {
        original: data,
        processed: AnotherObj {
            reference: &data
        }
    }
}

可以用 Rust 的术语来表达吗?

Is it possible to express this in Rust's terms?

这里我希望 ObjAnotherObjdata 具有相同的生命周期,当然比 new() 调用.

Here I'd like Obj, AnotherObj and data to have the same lifetime, and of course outlive the new() call.

推荐答案

基于您的要求的原始结构设计可能如下所示:

A raw design of the structs based on your requirements might look like this:

struct AnotherObj<'a> {
    original: &'a Vec<i8>, // Let's agree on Vec<i8> as your "data" type.
}

struct Obj<'a> {
    original: Vec<i8>,         // <-------------------+
    processed: AnotherObj<'a>, // should point here --+
}

但是,开始工作非常棘手(就我个人而言,我无法做到),因为您希望 AnotherObj<'a> 中的 'a 成为生命周期原始.但是,您必须为 Obj<'a> 提供生命周期,因此您必须指定 Obj<'tbc> 其中 'tbc 是要创建的 Obj 的生命周期.

However it's very tricky to get working (personally, I wasn't able to) because you want the 'a in AnotherObj<'a> to be the lifetime of original. However you must supply a lifetime to Obj<'a> and thus you would have to specify Obj<'tbc> where 'tbc is the lifetime of the Obj to be created.

我建议以下替代方案:

为什么不呢?Obj 将拥有 AnotherObj,因此它仍然可以访问 original 作为嵌套子项:

Why not? Obj will own AnotherObj, so it can still have access to original as a nested child:

pub struct AnotherObj {
    original: Vec<i8>,
}

pub struct Obj {
    processed: AnotherObj,
}

pub fn new() -> Obj {
    let data = vec![1,2,3];

    Obj {
        processed: AnotherObj {
            original: data,
            // ...
        }
    }
}

// access as obj.processed.original, you can even create a getter `fn original(&self)`

2.共享指针设计

直接使用引用计数的指针:

2. Shared pointer design

Straightforward use of refcounted pointers:

use std::rc::Rc;

pub struct AnotherObj {
    original: Rc<Vec<i8>>,
}

pub struct Obj {
    original: Rc<Vec<i8>>,
    processed: AnotherObj,
}

pub fn new() -> Obj {
    let data = Rc::new(vec![1,2,3]);

    Obj {
        original: data.clone(),
        processed: AnotherObj {
            original: data.clone(),
        }
    }
}

3.使用原始指针

选项 1. 和 2. 会给你带来安全的 Rust 神的安心,因此我不推荐这第三个选项.为了完整起见,我仍然把它贴在这里.注意:它可以编译,但我从来没有在运行时测试过它,所以它可能会咬人.下面只有安全代码,但是当您想取消引用原始指针时,您必须进入 unsafe 区域.

use std::ptr;

pub struct AnotherObj {
    original: *mut Vec<i8>,
}

pub struct Obj {
    original: Vec<i8>,
    processed: AnotherObj,
}

pub fn new() -> Obj {
    let data = vec![1,2,3];

    let mut obj = Obj {
        original: data,
        processed: AnotherObj {
            original: ptr::null_mut(),
        }
    };
    obj.processed.original = &mut obj.original as *mut Vec<i8>;

    obj
}

这篇关于拥有一些数据和对数据的引用的结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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