本記事、ちょっと前に書いたけど公開しわすれていた。
Rust、まぁなんとなくわかってきた。データ構造のコードはそれなりに練習になった。
- unsafeなしのsingle-linked-listをBoxを使って書いた。やってみたらそれほど難しくない。あとイテレータは戻る必要がないので実は簡単。なんでdouble-linked-listにする必要あるんだろう? cursorというAPIは戻れるようになっているが、これはexperimentalとのことで手元では実装していない。実装するならzipperを使うことになると思うが可能ではありそう。ただzipperの構造はちょっと複雑かもしれない
- そもそも連結リストだけど途中に要素を差し込んだり途中の要素を削除したりすることもないので、複雑さはそこまででもなかった
- removeとかあるけど、リストに対してインデックスの数値を渡してO(n)で削除するインタフェースになっている。連結リストの存在意義とは……?
- 作ったリストを2つ使ってqueueを書いた。Chris Okasakiの本に書いてあるやつ。これはかなり簡単
- 興がのってきたので binomial heap と fibonacci heap も書いてみて、テストをいろいろ書いてみたりした。なかなか楽しい。うまいことしてベンチマークを書いて計算量が理論どおりになっているかを調べたいところだが
オーナーシップ、copy/move、moveによる無効化はいまだに戸惑うし、ルールはわかりづらいように思える。とくにstructのフィールドの一部をもちだしたいときのエラーメッセージが「copyにしましょう」だったりするのがわかりづらい。意図せずコピーしているケースもありそう。
moveが実際にどのようなオペレーションになるかがまだよくわかっていない。ローカル変数同士、ヒープ変数同士であれば変数の指し示す対象を切り替えるだけの操作で済む気もするが、実際にはコピーになっていて意外と高コストだったりしないんだろうか? もっともほとんどのmoveではshallow copyなので、そこまで遅いことはないのかもしれない。
まぁC++でもクラスや構造体はmoveできるが、std::unique_ptrを使うほうがよくあるし、Boxなどを使うほうが普通なのかもしれん。
そろそろデータ構造のおさらいだけじゃなくて、何かツール的なものを作ってみたい。さてなにを作ろうかね。