Rustのソースを眺めていて、また分からないものを見つけました。唐突に現れた Box<i32> なるもの。大文字(アッパーキャメルケース)で書かれていることをみると型、それもジェネリック型に見えます。Boxって何なの?調べてみたら値を「ボックス化」してくれるんだとか?ますます分からん?
※「やっつけな日常」投稿順 indexはこちら
結論から言えば、BoxというのはRustの標準ライブラリで定義されている型のようです。だから、何も宣言せずに「唐突」に使っても怒られないみたいです。
それに「ボックス化」、これは値をヒープ上に割りあてることだと。ボックス化をする型なのでBox、ベタなネージミングです。
いつもお世話になっております『Rust By Example 日本語版』さまの以下のページから1か所引用させていただきます。
ボックスとは正確にはヒープ上におかれたTの値へのスマートポインタです。ボックスがスコープを抜けると、デストラクタが呼ばれて内包するオブジェクトが破棄され、ヒープメモリが解放されます。
例によって分かったような、まだ引っかかるような。
とりあえずサンプルコードを書いてみた
分からなくてもBox使ってみるもんだ、と。こんな感じ。
fn sample_box() -> Box<i32> { let temp: i32 = 123; Box::new(temp) } fn sample2_box(arg: Box<i32>) { println!("BOX in SUB: {}",arg); } fn sample_i32(arg: i32) { println!("i32 in SUB: {}",arg); } fn main() { let ax = 456; println!("i32: {}",ax); sample_i32(ax); println!("i32: {}",ax); let bx = sample_box(); println!("BOX: {}",bx); println!("BOX*: {}",*bx); sample2_box(bx); // println!("BOX: {}",bx); }
比較のため、普通にスタックの上に値がおかれる変数 ax をまずおいて、その後Boxしてみています。
最後の方に // でコメントアウトしてあるところがありますが、ここをコメントアウトしないと、以下のようなエラーになります。
sample2_boxという関数に Boxを渡してしまうと、その「所有権」はmainの手を離れてしまうので末尾の行ではエラーとなると。ちゃんとヒープ上のオブジェクトの挙動をしているようです。
動作確認
末尾行をコメントアウトして実動作を確かめたものが以下に。
Box使って、ヒープ上にオブジェクトを置くことができるのは分かったけれども、*つけても、つけなくてもBoxの中の値にアクセスできるのは何故?便利なような、Rustの挙動が読み切れてないと恐ろしいような。