Rust
RustはC++に取って代われるのか
Rustは面白い。
正直、アセンブリとCの他にこんな面白い(低レベルな)言語が出てくるとは思わなかった。
メソッドチェーンで記述できるし、C++のユニークポインタと同じようなスマートポインタが言語レベルで実装されていることもあり、最初Rustをオブジェクト指向型言語だと勘違いし「C++で書けるものはほぼすべて書き直すことができる言語なのだろう、やがてC++に取って代わるのだろうな」と思っていた。
しかしいろいろ書くようになってくると、そうでもないような気がしてきた。
「さてはお前、オブジェクト指向型言語ではないな?」と思うようになってきたのだ。
Rustはオブジェクト指向型言語のような書き方ができるのだが、コードを書いていると内部で「オブジェクト(データとコードが一塊になったもの)」の生成をしていないように見える。
例えば構造体にメソッドをインプリメンテーションする際、第一引数に &self を受け取るように書く必要がある。
fn hoge(&self, a: i64, b: i64) {
println!("{}", a + b);
}
しかし呼び出し元の第一引数にはそんなもの書かなくていい。
s.hoge(10, 20);
いったい「&self」とは何を受け取っているのか。
それは「s.hoge(10, 20)」の「s」、正確には「sへのポインタ」だ。(Box化した場合はポインタの参照(エイリアス)を受け取っている)
sは構造体なので、つまり「構造体へのポインタを第一引数として呼び出している」というわけだ。
上のメソッド呼び出しをC言語風に書くと、
hoge(&s, 10, 20);
となり、Cを書く人には見慣れたコードになる。
Rustで実際にこのコードを書くとコンパイルエラーになってしまうが、どの構造体に紐付いているのかを明示して
S::hoge(&s, 10, 20);
このように書けばコンパイルできるしちゃんと動く。
Rustの関数呼び出しはメソッドチェーンで記述できるのだが、その意味合いが他のオブジェクト指向型言語とは異っている。
C++だと「s.hoge()」は「sオブジェクト内のhogeメソッドを呼び出す」と解釈するが、Rustでは「s構造体に紐付いたhoge関数の第一引数にs構造体へのポインタを与えて呼び出す」と解釈する。
C++でいうところの「オブジェクト」は生成できないのだが、第一引数をメソッド名の前に持ってきてメソッドチェーンで書けるのがRustだ。(なんでもかんでもそう書けるわけではなく、その型にインプリメンテーションされた関数名があるケースのみ。ちなみにこういう書き方ができるのはRustだけではない)
なのでオブジェクト指向型言語のように錯覚するのだが、内部でやっていることは手続き型言語そのものだ。
例えば、アセンブリの
add eax, edx
というADD命令を
eax = add(eax, edx)
と書くとC言語っぽくなるが
eax = eax.add(edx)
と書くとC++っぽくなるというだけで、やっていることは全部同じ、というイメージだろうか。(例えがアセンブリで申し訳ない)
ともかく、Rustはオブジェクト指向型言語ではない。
Cで書いたものはRustで書き直しやすいのだが、C++で書いたものをRustで書き直そうとすると急に書きにくく感じることがある。
「C++だとこう書けるけど、Rustだとどう書けばいいんだ?」みたいなことになるのだ。(あとキャストだらけになる・・私だけ?)
結果、力まかせなコードになってしまって「コンパイルは通ったし一応動くんだけど、これで合ってるのか?」となることが最近増えてきたような気がする。
特に構造体の継承ができない(トレイト単位でしか継承ができない)ということ、関数のオーバーライドができない(仮想関数を書く場所が無くて動的ポリモーフィズムが実現できない)こと、ジェネリックな関数で受け取った構造体に紐づいた関数が呼び出せないことが個人的にはストレスに感じる。(あくまでもRustをC++の代わりにしようとした場合に)
Rustは「CとC++の中間的なこと」をするときにとても書きやすいと思う。
Cではやや役者不足、というようなときにRustだと書きやすいのだ。
StringやVectorなどはCからしてみるととてもありがたいし、メモリの境界に対してピリピリし続けなくてもいい。
ちょっとした関数なんかはクロージャでその場に書けるのが便利だし、多値を返すような関数もタプルでスッと書けて気持ちいい。
データを生成してそのポインタを返せる関数が書けるというのも最高だ。
呼び出し先でmallocして呼び出し元でfreeするというようなバグの予感しかしないコードを書くことが皆無になるという点でも、本当にRustは素晴らしい言語だ。
あとなんといってもGCでないのがいい。
C++のスマートポインタは発明だったが、それをC並の低レベル言語に取り入れてくれたRustはまさに神だ。
結論としては、「RustはC++に取って代われなくていい、RustはRustのままでいてくれ」というところだろうか。
インタプリタ型言語などを作るときにも大活躍しそうな気がする。
ただまあ・・、拡張され続けてカオスなことになっているC++に取って代われるような、"Rust+=1"が出てくれると世界中に喜ぶ人がたくさんいるかもとは思う、私を含めて。
とか書いていたら、「Rust+=1」ではないが、C++の後継言語である「Carbon Language」が発表されたようだ。
|