自己参照構造体は作ることが出来ない
Qiitaからのメモ
【Rust】構造体に自身のフィールドの参照の配列を持たせる方法 - Qiita
struct Bullet<'a>(&'a Texture); struct Enemy<'a> { bullet_texture: Texture, bullets: Vec<Bullet<'a>> } impl<'a> Enemy<'a> { fn new(bullet_texture: Texture) -> Self { Enemy { bullet_texture, bullets: vec![] } } fn shot(&mut self) { self.bullets.push(Bullet(&self.bullet_texture)); } }
回答
https://qiita.com/9laceef/items/aa0d7e1bd5041a1857d5#comment-40efdbbd19675bae1ab3
コメントがついていますが補足します。自己参照構造体はRustでは基本的にはできないです。 ライフタイムだけの問題ではなく、参照が無効になってしまうケースがあるのです。 Rustでは値の場所が変わりうるのでデータ型が移動したら参照が無効になってしまいます。 例えば以下のコードがもし動くとしたら、
fn main() { let mut enemy = Enemy::new(Texture); enemy.shot(); let enemy2 = enemy; }
+----------------------+ | | | enemy | | +-------+---------+---------+ | | Enemy | texture | bullets | | +-------+---------+---------+ | ^ | +-----+ | | | +--------+ +->| bullet | Vecの中身 +--------+
それが let enemy2 = enemy とするとenemyがムーブするので元あったenemyの領域が無効になります。その結果以下のような無効なメモリ領域を指すBulletが出来上がってしまいます。
enemyの残骸 +-------+---------+---------+ | xxxxxxxxxxxxxxxxxxxxxxxxx | +-------+---------+---------+ ^ +-----+ | +--------+ +->| bullet | Vecの中身 | +--------+ | +------------------------+ enemy2 | +-------+---------+---------+ | Enemy | texture | bullets | +-------+---------+---------+
enemy1の生成
enemy2 = enemy1 あと 参照とはフィールドのアドレスを渡すことであることがわかる