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

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

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

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

在这里,我希望ObjAnotherObjdata的生命周期 相同,当然比new()的生命周期 更长.

推荐答案

基于需求的 struct 的原始设计可能如下所示:

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人成为original人的一生.然而,您必须为Obj<'a>提供一个生存期,因此您必须指定Obj<'tbc>,其中'tbc是要创建的Obj的生存期.

我建议采取以下替代方案:

1. Make AnotherObj actually own the original

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

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.共享指针设计

直接使用refcounted指针:

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 神的宁静,因此我不推荐第三种 Select .为了完整起见,我还是把它贴在这里.注意:它可以编译,但我从未在运行时测试过,所以它可能会有用.下面只有安全代码,但是当你想要取消对原始指针的引用时,你必须进入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
}

Rust相关问答推荐

使用DeliverProcess W或ShellExecuteExW复制Windows Run行为?

关于Rust 中回归的逻辑

在Rust中,在实现特征`Display`时,如何获取调用方指定的格式?

告诉Rust编译器返回值不包含构造函数中提供的引用

类型批注需要静态生存期

我们能确定Rust会优化掉Clone()吗?如果它会立即掉落?

在复制类型中使用std::ptr::WRITE_VILAR进行内部可变性的安全性(即没有UnSafeCell)

如何使用reqwest进行异步请求?

处理带有panic 的 Err 时,匹配臂具有不兼容的类型

如何从宏调用闭包?

如何在 Rust 中编写一个通用方法,它可以接受任何可以转换为另一个值的值?

如何以与平台无关的方式将OsString转换为utf-8编码的字符串?

std mpsc 发送者通道在闭包中使用时关闭

如果不满足条件,如何在 Rust 中引发错误

如何将这些测试放在一个单独的文件中?

类型判断模式匹配panic

哪些特征通过 `Deref` 而哪些不通过?

Rust 中 `Option` 的内存开销不是常量

Rust 生命周期:不能在方法内重新borrow 可变字段

为什么这里需要类型注解?