修改切片/引用数组

问题描述 投票:0回答:1

我是 Rust 新手,我很难理解一些引用/借用行为。

这是一个无法编译的片段。我正在尝试创建一个

u64
“切片”数组,我想修改其值,然后稍后访问:

fn main() {
    // Initialize an array of "slices" with dummy data
    let mut refs: [&[u64]; 4] = [&[0; 2]; 4];

    // Write some computed values to the array
    for i in 0..refs.len() {
        // ...
        // some computation to get `x` and `y`
        // ...
        let data: [u64; 2] = [x as u64, y as u64];
        let data_ref: &[u64] = &data;
        refs[i] = data_ref;
    }

    // Read the computed values from the array
    println!("{}", refs[3][0]);
}

编译器返回:

error[E0597]: `data` does not live long enough
  --> src\main.rs:8:32
   |
7  |         let data: [u64; 2] = [x as u64, y as u64];
   |             ---- binding `data` declared here
8  |         let data_ref: &[u64] = &data;
   |                                ^^^^^ borrowed value does not live long enough
9  |         refs[i] = data_ref;
10 |     }
   |     - `data` dropped here while still borrowed
...
13 |     println!("{}", refs[3][0]);
   |                    ------- borrow later used here

虽然我知道

data
的作用域是在
for
循环内,并且它将不再存在于
for
循环之外(因此将
refs[i]
设置为引用
data
应该会导致编译器错误由于
refs
data
更长寿),我不确定是否有其他方法可以正确设置
refs
的值。

声明、初始化然后从这样的数组中读取“切片”值的适当(“生锈”)方法是什么?

rust slice borrow-checker
1个回答
0
投票

问题在于切片引用数据位于“其他地方”。它们也不能真正比它们引用的数据更长久。

如果你定义

let data: [u64; 2] = [x as u64, y as u64];

在循环中,

data
会随着每次迭代而消失。因此

你不能拥有

let data_ref: &[u64] = &data;
refs[i] = data_ref;

因为,当循环结束时,它会使

refs
包含对不再存在的数据的引用 (
data
)。

在您的示例中,您可以将切片替换为 2 元素数组,如下所示:

fn main() {
    let mut arrays = [[0; 2]; 4];

    // Write some computed values to the array
    for i in 0..arrays.len() {
        // ...
        // some computation to get `x` and `y`
        // ...
        let x = 1;
        let y = 2;
        arrays[i] = [x, y];
    }

    // Read the computed values from the array
    println!("{}", arrays[3][0]);
}

代码打印

1

如果您确实需要一个切片数组(例如,当您从外部获得

refs
时),我认为您可能需要将数据复制到切片中,如下所示:

fn main() {
    // Initialize an array of "slices" with dummy data
    // The array doesn't need to be mutable (we don't modify it)
    // The slices have to be mutable (we modify them)
    let refs = [&mut [0; 2], &mut [0; 2], &mut [0; 2], &mut [0; 2]];

    // Write some computed values to the array
    for i in 0..refs.len() {
        // ...
        // some computation to get `x` and `y`
        // ...
        let x = 1;
        let y = 2;
        refs[i].copy_from_slice(&[x, y]);
    }

    // Read the computed values from the array
    println!("{}", refs[3][0]);
}

(我在那里有这个丑陋的

[&mut [0; 2], &mut [0; 2], &mut [0; 2], &mut [0; 2]]
形式,因为
[&mut [0; 2]; 4]
不起作用——可变切片不是
Copy
)。

有关详细信息,请参阅

copy_from_slice
文档

© www.soinside.com 2019 - 2024. All rights reserved.