Cプログラマから見たRust
趣味でRustを触って見たので所感をまとめます。
普段Webのバックエンド書いてるんですが言語特性的にCを基準にしたほうが理解しやすかったので掲題の通り。
TL;DR
ここ十数年の言語工学の理論&実践の集大成としてCから正当進化したという印象。
コンパイラが論理的に厳格なメモリを管理をしている。
Cargo優秀かよ
コンパイル言語ですがスッと動かせて楽。
最近の言語なので流石によく整備されている感じ。
この辺はRuby/Typescript/Golangとかモダンな言語での試行錯誤の集大成って感じがする。
変数がデフォルトでimmutable
ほーいいじゃないか
こういうのでいいんだよ、こういうので
変数再代入問題は遥か古から問題になってて、読み取り専用修飾子があったり、チェッカーで警告出したりしてるのはあるんだけどね。
変数なんて値が変わらないに越したことはないんよ。
(variableというのは実行時varibaleで十分であってスコープvariableである必要は殆どない)
Javaのコードでfinal祭りを拝んだり、C++でお前何回const言うねんと思った人は結構いるはず。
ただimmutableって後から言語仕様追加する場合はキーワード追加するしか無いのよね・・・
後発言語だから出来る思い切ったデフォルトimmutableは日和らずによくやった感がある。
暫定変数を全部immutableにすると変数の宣言が増えてぶつかりやすくなるんですけどShadowingのおかげである程度は名称使い回せるようになっててこれもよい。
初出がわからないんですけど既存言語からの輸入っぽい。(自分の知る限りGolangにもあったので)
符号なし整数・・・お前小さくなったなぁ・・・
Static Typingなので数値変数の型はしっかりしないとね!
u32
unsigned integer
くん・・・見ない間にずいぶん小さくなって・・・
ていうか integer
の部分が跡形もないじゃないか・・・・
所有権はGCの正当進化っぽい形
大混乱malloc/freeブラザーズに新たな挑戦者が現れました!
free忘れに嫌気が差して参照カウンタ制御とGCに任せてみたものの、どっからか参照されっぱなしでリークしてんなしかも開放クソおせぇよ問題の一つの答え。
基本的に参照カウンタは1でええやろという大胆さに惚れる。
あとデストラクタくんがトレイトでうまくGCに飼いならされてる。
変数のポインタ引き回しも厳しい
ヒープの所有権ほどでは無いにしても、まぁまぁ厳しい。
DBの専有ロックと共有ロックとまぁ同じ考え方なのだが、プログラムレベルで厳格にやるか。
Cの癖でポインタをほいほい引き回すとアクセス出来ねぇってなるので気をつけたいところ。
複数引き回したい時には別にポインタ管理構文があって、基本的にはC++のポインタ管理の知見を輸入している感じがする。
この辺のコンパイラが面倒見きれないような細かいメモリ制御は自分で責任持って管理しろということなのだろう。
おかえり構造体
クラスなんて概念初めから存在しなかった。いいね?
御当地enumはunionっぽい
言語ごとにちょくちょく仕様が違うenumではあるがRustは結構違う。
Cではintのdefineまとめたやつ、、、『値の列挙』を型としてパックした感じだったし他の言語でもString値とかに拡張されつつもそんな感じ。
なんだけどRustの場合はどっちかと言うと『型の列挙』的な動きをしてて列挙要素に値をもたせられる。
列挙要素と列挙型がinstance-ofの関係じゃなくてis-aの関係。
あーこれどっかで見たなと思ったらunion型じゃないか。懐かしいなお前。
Cでunion持つ要素貰ったら「で?お前どの型なわけ?」って他の要素みて確認しないといけなかったんだけど、match文とか様々な構文がちゃんとフォローしてくれていて、なんかすごい進化してる。
nullable型もここに統合されていて、構造体の拡張定義とかもこれで出来る。
継承なんてなかった。いいね?
マルチスレッドもメモリ管理難しめ
並列処理で共有変数触ると当然問題の宝庫なのだけど、そこもコンパイラで厳し目に縛ってる。
起動時にmoveで値の参照権限をスレッドに完全に移してしまうというのが基本的な考え。
いろんな抜け方はあるんだろうけどchannelがきちんと実装されてるので共有変数使わずに基本的にはちゃんとそっち使いましょうねってことかなと。
メモリ共有方法は参照するだけでもかなり手間がかかる。
- MutexオブジェクトでWrapして排他ロック掛けれるようにする
- ArcオブジェクトでWrapして非同期に参照カウンタをいじれるようにする
- 所有権を複製してスレッドに渡す
Discussion