Open4

Rustで禿げてる箇所

nesken7777nesken7777

前提

  • 自分はそもそもRustがプログラミングを学んだ第一言語であり慣れ親しんでいるため、他の言語に触れるとより「うわ」と反応してしまう。
  • その上で「じゃあRustでキモいと思ったことはねえのかよ」というツッコミが自分の中で発生するため、あえてRustでキモいと思った部分を発生した都度書いていく。
nesken7777nesken7777

自動参照外し

「自動参照外し」ってGoogleで検索するだけでRustに関する記事がいろいろ出てくる。
https://doc.rust-lang.org/nomicon/dot-operator.html
https://qiita.com/kerupani129/items/8dba9f5bb2c009c4d08d
↑ここらに詳しく書かれてる

Rustは参照に対するドット演算子によるアクセスは勝手に参照を外してくれる。これを最初見誤っていた。

以前C++で書かれたAviUtlのあるプラグインを写経する際、全ての関数全体をunsafeで囲み参照を一切使わず生ポインタで処理を書くという危険極まりなく今の自分では見てられないコードを書いていた。

(https://anssi-fr.github.io/rust-guide/07_ffi.html#references-and-pointers
追記。どうやらFFIの場合は逆に参照はおすすめされず、ポインタを使ったほうが良いらしい。)

その時、ポインタと参照を同じようなものと見なしていたため「確かRust by Exampleで構造体の参照をしてるはずなのに参照外し演算子*書かれてなくて不思議だったけどこれが正しいんだろうな」と考え、生ポインタの指している先のメソッドやフィールドに*無しでアクセスしようとした。しかし、これがコンパイラに「(*a).bにアクセスしたいんじゃないの?」と叱られたため、「やっぱり*つけないといけないじゃん」みたいな気持ちになった。こんなことをしていたがためにドット演算子に対する認識が歪んだままとなった。

ドット演算子は基本的に自動参照外しを行う。これが示すことは、型に実装されたDerefトレイトが示す先にドット演算子がアクセスしているということである。生ポインタ型にはDerefは実装されていない(?)が、参照には実装されている
これが一番最初に禿げた点。一度、「メソッドだと参照外しがされる」という勘違いも発生していた。

また、この性質によりまた混乱するような書き方ができるようになっている。

let x:i32 = 52;
let y:i32 = &x + 1; //53

この書き方が成立するのだ。xへのi32ポインタに1サイズ分離れた数が入るように見えて、実際にはyにはx+1が束縛される。

https://doc.rust-jp.rs/rust-by-example-ja/trait/ops.html?highlight=Add

↑にあるように、ほとんどの演算子はトレイトによって提供されるメソッドの糖衣構文である。つまりドット演算子により参照外しされるということなのだ。この記法が関数の引数として現れたのを見た時は、「なんでこれで通るんだ」と思った。

このように参照は多くの場合で自動参照外しが行われるため、Rustにおける参照はCのポインタという認識より「値を参照させていただいている」という認識のほうがいいのではないかと考えを改めさせられた。

さらに、これに加え「参照外し型強制」というこれもまた直感的ではない書き方ができるものがあるが、それはまた別の話として実際に自分が禿げた時に追加する。

nesken7777nesken7777

"&x"によるパターンマッチング(参照を分配)

これに関してはただの人の好みではある。
https://doc.rust-jp.rs/book-ja/ch18-03-pattern-syntax.html#参照を分配する
↑に書いてある通り、参照である値に参照としてパターンマッチング(←日本語正しい?)させ、マッチングした際に用いた&を外すことでまさに「参照外し」しているかのような書き方ができる。リンク先の用法としては構造体の分配に加え参照も外したいため、このような書き方しかできないのは仕方ないが、自分としてはパターンマッチングにそこまで複雑なのを見たくないんです…*で参照外しするほうが直感的に分かりやすいんです…;;

nesken7777nesken7777

マクロ

マクロてめえだけはマジで許さんどんな挙動するんかマジで分からんお前が一番禿げるわアホ
Rustの明確さを破壊するようなマクロ(特に手続き型マクロ)のあり得なさとか衝撃的な展開とかやめてくれ

「構造体宣言したかと思ったらstatic変数が生成されてた」っていうマクロに遭遇しましたの…;;
そうだねこれがメタプログラミングだね…お前が魔法だ——————
出来ればマクロは書かないでね^^; マジで。
dtolnayのリポジトリで修行するしかないんかな