我有一个struct Board
,其中包含一个元素rows: [[&'a mut Tile; 7];7]
由于生命周期,我不知道如何通过impl Board {}
块中的构造函数进行初始化,因此我尝试在main
函数中对其进行初始化。
遗憾的是,rows = [[&mut Tile::def(); 7]; 7]
不起作用,因为Rust想要复制引用&mut Tile::def()
。 (其中Tile::def()
是Tile
的构造函数)。
有没有办法初始化此数组,使得每个元素(i,j)都是对不同Tile
的引用?
当前,唯一有效的解决方案是
let mut rows = [[&mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def()],[&mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def()],[&mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def()],[&mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def()],[&mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def()],[&mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def()],[&mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def()]];
let board = Board { rows : rows, ...};
由于明显的原因,这是不令人满意的。
我尝试过创建一个将
[[Tile; 7]; 7]
转换为所需数组的函数,但是我遇到了多次借用该数组的可变元素的可能性。 最佳答案
&mut
不仅是“具有突变的指针”。这是借来的。这意味着它不能拥有Tile
,它必须属于其他地方。
这种方法
let mut rows = [[&mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def()],[&mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def()],[&mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def()],[&mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def()],[&mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def()],[&mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def()],[&mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def(), &mut Tile::def()]];
之所以起作用,是因为每个单独的
Tile::def()
都会创建一个新的临时Tile
,并且&mut
会导致该临时文件“提升”到堆栈中-有关更多信息,请参见Why is it legal to borrow a temporary?。但这不是解决此问题的方法:您需要一些东西来拥有Tile
。例如,您可以创建一个
Vec<Tile>
并在rows
中填充对Vec
成员的引用。但这并不能解决您的初始化问题,真正的答案是更容易的:您需要拥有的指针,因此请使用Box<Tile>
而不是&mut Tile
。Box
没有实现Copy
,但是它实现了另一个使这项工作更加容易的特征:Default
。impl Default for Tile {
fn default() -> Self {
Tile::def()
}
}
fn main() {
let mut rows: [[Box<Tile>; 7]; 7] = Default::default();
}
根据
Tile::def
的功能,您也可以使用#[derive(Default)]
而不是手动实现它。我鼓励您考虑另外一个选择:将所有
Tile
存储在Vec
中,但是通过索引而不是任何类型的指针来引用它们。交换两个索引很便宜,可以根据需要轻松增加Vec
,可以将rows
与后备存储一起存储,而不会造成生命周期问题,并且比存储所有索引更易于缓存(这可能意味着更好的性能)。 Tile
在单独的分配中。但这并不一定在所有情况下都是理想的。关于rust - 初始化对struct的可变引用的数组,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53788733/