Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/apache-flex/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 如何创建一个结构,其中一个字段引用另一个字段_Rust - Fatal编程技术网

Rust 如何创建一个结构,其中一个字段引用另一个字段

Rust 如何创建一个结构,其中一个字段引用另一个字段,rust,Rust,我有以下问题:我有一个数据结构,它是从缓冲区解析的,并且包含一些对这个缓冲区的引用,所以解析函数看起来像 fn parse_bar<'a>(buf: &'a [u8]) -> Bar<'a> 不起作用,因为在BarWithBuf值的构造中,buf被移动,但我们借用它进行解析 我觉得应该有可能按照 fn make_bar_with_buf<'a>(buf: Box<[u8]>) -> BarWithBuf<'a> {

我有以下问题:我有一个数据结构,它是从缓冲区解析的,并且包含一些对这个缓冲区的引用,所以解析函数看起来像

fn parse_bar<'a>(buf: &'a [u8]) -> Bar<'a>
不起作用,因为在BarWithBuf值的构造中,
buf
被移动,但我们借用它进行解析

我觉得应该有可能按照

fn make_bar_with_buf<'a>(buf: Box<[u8]>) -> BarWithBuf<'a> {

    let mut bwb = BarWithBuf {buf: buf};
    bwb.bar = parse_bar(&*bwb.buf);
    bwb
}
fn使用{
设mut bwb=BarWithBuf{buf:buf};
bwb.bar=parse_bar(&*bwb.buf);
bwb
}
为了避免在解析
后移动缓冲区,我不能这样做,因为整个
条带buf
结构必须一次性初始化。 现在我怀疑我可以使用
不安全的
代码来部分构造结构,但我不想这样做。

解决这个问题的最好办法是什么?我需要不安全的代码吗?如果我这样做,在这里这样做安全吗?还是我完全走错了方向,有更好的方法将数据结构及其底层缓冲区绑定在一起?

我认为你是对的,没有不安全的代码是不可能做到这一点的。我会考虑以下两个选项:

  • 栏中的引用更改为索引。该框的内容不会受到借用的保护,因此如果不小心,索引可能会变得无效。然而,索引可能以更清晰的方式传达引用的含义

  • 移动到
    ,并在
    的实现中添加一个函数
    buf()->&[u8]
    ;在
    中存储索引而不是引用。现在,
    Bar
    是缓冲区的所有者,因此它可以控制其修改并保持索引有效(从而避免选项1的问题)

  • 根据DK下面的建议,将索引存储在
    BarWithBuf
    (或在助手结构
    BarInternal
    )中,并向
    BarWithBuf
    的实现中添加一个函数
    fn bar(&self)->bar
    ,该函数动态构造一个
    bar


  • 这些选项中哪一个最合适取决于实际的问题背景。我同意结构的某种形式的“成员对成员构造”对生锈非常有帮助。

    我从来没有想到,如果没有不安全的代码,是否可以对结构的其他成员进行内部引用。我看不出借阅检查器如何跟踪像这样的借阅…这个问题太老了,我不想以重复的方式关闭它,但大多数访问此网站的人可能应该改为签出。我已经考虑了第一个选项,但我不是特别喜欢它。我很难理解你的第二个建议,你能详细说明一下吗?@fjh我相信Adrian建议你将
    包装成一种类型,该类型有一个返回临时
    的方法。其思想是您存储一个“可移植”形式的
    (类似于盒装数据的索引),该方法根据需要构造一个
    ,使用
    &self
    的生命周期来保证安全。@DK。不太清楚,但我澄清了选项2,并将您的建议添加为选项3。谢谢!我可能会咬紧牙关,使用
    String
    Vec
    而不是引用缓冲区来回避整个问题。基于索引的解决方案感觉有点老套,对我来说不太合适,因为缓冲区中的一些引用是
    &str
    ,所以我必须反复验证utf编码或使用不安全的代码。
    fn make_bar_with_buf<'a>(buf: Box<[u8]>) -> BarWithBuf<'a> {
        let my_bar = parse_bar(&*buf);
        BarWithBuf {buf: buf, bar: my_bar}
    }
    
    fn make_bar_with_buf<'a>(buf: Box<[u8]>) -> BarWithBuf<'a> {
    
        let mut bwb = BarWithBuf {buf: buf};
        bwb.bar = parse_bar(&*bwb.buf);
        bwb
    }