Code Fix

中級

E0072: recursive type has infinite size の原因と直し方

構造体が自分自身の型を直接フィールドに持つと、サイズが無限になってしまいコンパイルエラーになります。Boxなどのポインタ経由の間接参照を挟むことで、サイズを確定させる必要があります。

エラーメッセージの読み方

error[E0072]: recursive type `Node` has infinite size
E0072
エラーコード — `rustc --explain E0072` で詳しい説明が見られます
recursive type `Node` has infinite size
詳細メッセージ — 何が問題だったか

このエラーが出る典型パターン

パターン1

 1  struct Node {
 2      value: i32,
 3      next: Option<Node>     ,
                      ^
 4  }
 5  fn main() {
 6      let n = Node { value: 1, next: None };
 7      println!("{}", n.value);
 8  }
error[E0072]: recursive type `Node` has infinite size

Nodeが自分自身を直接含むとサイズが確定しません。Boxを挟んでポインタ経由にする必要があります。

直し方: Option<Node>Option<Box<Node>> にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  struct ListItem {
 2      data: i32,
 3      child: Option<ListItem>     ,
                         ^
 4  }
 5  fn main() {
 6      let n = ListItem { data: 1, child: None };
 7      println!("{}", n.data);
 8  }
error[E0072]: recursive type `ListItem` has infinite size

再帰的な構造体の典型的な解決策は、フィールドをBoxで包んでポインタとして持つことです。

直し方: Option<ListItem>Option<Box<ListItem>> にします。

この問題を解いてみる →

パターン3

 1  struct TreeNode {
 2      value: i32,
 3      left: Option<TreeNode>     ,
                        ^
 4  }
 5  fn main() {
 6      let n = TreeNode { value: 1, left: None };
 7      println!("{}", n.value);
 8  }
error[E0072]: recursive type `TreeNode` has infinite size

木構造のようなデータ構造では、子ノードへの参照は必ずBoxやRcなどの間接参照にする必要があります。

直し方: Option<TreeNode>Option<Box<TreeNode>> にします。

この問題を解いてみる →

パターン4

 1  struct Chain {
 2      id: i32,
 3      next: Option<Chain>     ,
                       ^
 4  }
 5  fn main() {
 6      let n = Chain { id: 1, next: None };
 7      println!("{}", n.id);
 8  }
error[E0072]: recursive type `Chain` has infinite size

コンパイラは構造体のサイズをコンパイル時に確定させる必要があるため、無限に自己参照する定義は許されません。

直し方: Option<Chain>Option<Box<Chain>> にします。

この問題を解いてみる →

パターン5

 1  struct Frame {
 2      depth: i32,
 3      parent: Option<Frame>     ,
                         ^
 4  }
 5  fn main() {
 6      let n = Frame { depth: 1, parent: None };
 7      println!("{}", n.depth);
 8  }
error[E0072]: recursive type `Frame` has infinite size

Box<Frame>はヒープ上のFrameへのポインタなので、Frame自体のサイズによらず一定サイズになります。

直し方: Option<Frame>Option<Box<Frame>> にします。

この問題を解いてみる →

よくある誤解

「Option<Node>のように包んでおけば、再帰的な構造体でもサイズは決まるはず」という思い込みは誤りです。Optionは中身をそのまま埋め込む型なので、Node自身のサイズがまだ確定していない問題は解決しません。ポインタであるBoxを挟んで初めて、サイズが確定します。

まとめ

E0072: recursive type has infinite sizeは中級でつまずきやすい項目です。上の5パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)