やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

RustのスマートポインタBox<T>

 ヒープに格納する。(スタックでなく) 型定義を自己参照するときに有用。

成果物

参考

コード

生成

src/main.rs

fn main() {
    let b = Box::new(5);
    println!("b = {}", b);
}

 i32型の値5はヒープ領域にメモリ確保された。

再帰

コンスリスト

src/main.rs

enum List {
    Cons(i32, List),
    Nil,
}
use List::{Cons, Nil};
fn main() {
    let list = Cons(1, Cons(2, Cons(3, Nil)));
}

 コンパイルするとエラーになる。

$ rustc main.rs
error[E0072]: recursive type `List` has infinite size
 --> main.rs:5:1
  |
5 | enum List {
  | ^^^^^^^^^ recursive type has infinite size
6 |     Cons(i32, List),
  |               ---- recursive without indirection
  = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `List` representable

 Listの型定義が再帰のためサイズが無限大。

間接参照

 じつはエラーの下端にヒントがある。「関節参照(Box,Rc,&)を挿入しろ」。

  = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `List` representable

 間接参照とは、値を直接格納する代わりに、データ構造を変えて値へのポインタを格納すること。

Boxで実装する

src/main.rs

#[derive(Debug)]
enum List {
    Cons(i32, Box<List>),
    Nil,
}
use List::{Cons, Nil};
fn main() {
    let list = Cons(1,
        Box::new(Cons(2,
            Box::new(Cons(3,
                Box::new(Nil))))));
    println!("{:?}", list);
}

結論

 Box<T>は型定義で自己参照するときに有用。

対象環境

$ uname -a
Linux raspberrypi 4.19.42-v7+ #1219 SMP Tue May 14 21:20:58 BST 2019 armv7l GNU/Linux

前回まで