结构切片指向数据本身

dna*_*naq 5 rust

我有一个结构

struct Foo<'a> {
    buf: [u8, ..64],
    slice: &'a [u8]
}
Run Code Online (Sandbox Code Playgroud)

切片应该指向buf结构的字段.有没有办法构建这样的结构?就像是:

impl<'a> Foo<'a> {
    fn new() -> Foo<'a> {
        Foo {
            buf: [0, ..64],
            slice: ???? /* I don't know what to write here */
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我尝试执行类似下面的操作,则借用检查器会(正确地)抱怨,因为切片的生命周期将比结构更短.

impl<'a> Foo<'a> {
    fn new() -> Foo<'a> {
        let buf = [0, ..64];
        Foo {
            buf: buf,
            slice: buf.slice_from(0)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我意识到,对于这个简单的情况,我可以保留偏移量并手动调用切片函数:

struct Foo {
    buf: [u8, ..64],
    slice_from: uint,
    slice_to: uint
}
Run Code Online (Sandbox Code Playgroud)

然而,这个问题只是对拥有数据的结构的更一般用例的简化,并且引用了相同的数据,我想知道在Rust中是否可以(以安全的方式).

Vla*_*eev 7

不,你不能安全地做到这一点,因为一般来说这样的结构是不可移动的.假装它是可能的,你可以创建这样的结构:

let foo = Foo {
    buf: [0, ..64],
    slice: obtain_slice_somehow()
};
Run Code Online (Sandbox Code Playgroud)

slice字段现在是一个buf字段,特别是它包含一个指向buf目前位于堆栈上的指针.现在放入foo一个盒子并从函数中返回:

return Box::new(foo);
Run Code Online (Sandbox Code Playgroud)

foovalue现在被移动到堆,函数退出,释放它的堆栈内存.但是,slice指针没有调整为指向堆,因为一般不可能这样做,所以它留下了悬空,违反了内存安全.

  • 我能够欺骗借用检查器,错误报告在[此处](https://github.com/rust-lang/rust/issues/19537),相关的 reddit 帖子在[此处](http://www .reddit.com/r/rust/comments/2oappt/fooling_the_borrow_checker_bug/)。 (2认同)