&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
заставляет временное «продвижение» в стек - см. Почему законно заимствовать временный? для получения дополнительной информации.Но это не тот способ, которым вы должны решить эту проблему: вам нужно что-то, чтобы иметь Tile
s.
Вы можете, например, создать Vec<Tile>
и заполнить rows
со ссылками на членов Vec
.Но это не решает проблему инициализации, и реальный ответ проще: вам нужен владеющий указатель, поэтому используйте Box<Tile>
вместо &mut Tile
.
Box
hasnне реализует 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
в отдельных выделениях.Но это не обязательно идеально во всех ситуациях.