Rustコトハジメ

プログラミング言語Rustと競プロに関する情報をお届けします。

エディタ開発を始めてRustが全くわかってないことがわかった

前回の投稿から22日間無投稿だったそうです。

とりあえず競プロ勉強を一旦休憩するために3日ほど旅行に出て、帰ったら再開するつもりだったのですが、ずっとエディタ開発をしてしまいました。

3週間ほどやってようやく報告出来る程度には成果が出たので、一旦一区切りするためにその報告動画を作りました。一応、開発風景を毎日ライブしてるので、興味がある人は一度来てください。

www.youtube.com

この動画では、このエディタの設計などについて述べていますが、この記事では、Rustでエディタ開発をしてみて嵌った点を文章で共有したいと思います。主に参照関連です。

Rc<RefCell>地獄

Rustは並行プログラムを書くことをデフォルトにしてしまってるようなところがあり、シングルスレッドの明らかに安全なプログラムについても並行プログラムを書いてるかのようなコードが必要になることがあります。特に、オブジェクトを共有する場合です。単機能のクラスなど、小さな部品を書く時はこれらから無縁でいられますが、リアルアプリケーションにおいて色々な部品が関係しだすと突然RcやRefCellが必要になり、それが外に漏れ出します。一度使うと伝染します。

borrowborrow_mutが乱発するのは汚いので、何かシンタックスシュガーがないのかなぁと思いました。あるいは、DerefとかFromを活用するともう少しきれいに書けるのかも知れませんが良い方法が見つかりませんでした。なので今のコードは、表層に行くに連れてぐちゃぐちゃです。

RcRefCellを使うべき場面、使うべきでない場合について何か設計指針がドキュメントにまとまっていたら教えてほしいです。本でもいいです。

clone地獄

もともとエディタ開発を始めた理由が、「Rustの基礎はわかったと思うが、小さなプロジェクトをやって嵌らないとこれ以上理解が進まない」と思ったからです。Rustは所有権や参照が他の言語に比べて独特で、ともすれば一生コンパイラに怒られ続けることにもなりかねませんが、最悪でもRc<RefCell<T>>を使うことでコンパイラから逃げることが出来るため、他の慣れた言語ならばエディタを作ることは出来るでしょうから、Rustで書いてもエディタが永遠に動かないということはないだろうという見込みで駆け出しました。

なので、結果としては当然かも知れませんが、「よくわからないところはRcRefCellで逃げる」コードになってます。特に、イミュータブル参照で良さそうなのだがめんどくさいのでcloneして所有権を得てしまったり、オブジェクトが重い場合はRcで包んでからcloneするというイディオムを使ってる箇所があります。とにかく、参照から逃げるためにclone or copyしてます。わからなかったらclone。これでも性能が一気に落ちるというわけではないですが、最善ではないので少し気持ち悪い意味があります。

インターフェイスに参照やRcなどがにじみ出てしまう

例えば、Vecのgetの返り値はOption<&T>です。VecがT一般について書くことを考えると当然のインターフェイスだと思いますが、自分で書く型の場合は、本当に&Tを返すことが今後ずっと正しいことなのかどうかその時には判断出来ない場合があります。なぜかというと、Vecがこのように出来るのは、自分が返すオブジェクトについてメモリ領域を保持していることが明らかだからであって、作るものによっては、ある時にはそうだったかも知れないが、あとになってやっぱり参照を返すのは無理だったということになる場合もあるからです。例えば、関数の中で値を生成してその参照を返すことは出来ません。

このように判断が難しい場合があるので、後で後悔しないように、上で述べたように積極的にcloneしてしまってる意味があります。

総括

ここまで使ってみて、Rustは設計に所有権やライフタイムが関わってくるのが難しいと思いました。そういう意味では、ScalaなどGCがある言語の方がはるかに簡単です。Traitを返す場合にBoxなどで包むというのもそれ自体めんどくさいと思いますが、所有権を独占出来ると思って書いたら後になって実は共有する場合があったということがわかると、Boxではだめになったりするのも鬱陶しいところだと思います。私はここ数年で一番書いた言語がScalaなので、それを基準にして設計を考えると煩わしいと思うことが多かったです。

一方で、言語自体はまだ使い勝手の観点でも進化を続けてますし、こう煩雑に感じるのは私の経験不足から来てるだけかも知れないので、そういう意味では自分の中で期待は持てます。今後は、今回わからなかったトピックについて何か良い判断指針がないのか、調査して記事にしようと思います。