Rustで+++は許されない+ ++も許されない


そもそもRustにはインクリメント/デクリメント構文はありません、冪乗(**)の構文もありません。
(使いたい場合はそれぞれ x += 1;pow 系の関連関数1を使いましょう。)
なので参考記事の + ++2+++3 のような遊びは出来ません。

+++3の記事で &&&*** が使われていたので、そちらを検証していきます。

前提条件

  • ***を用いる時にデリファレンス(Deref)のオーバーロードを使わないようにします。
  • 元記事の構文とはズレるのと何でも出来てしまうので、マクロを使わないようにします。マクロ版記事4

&&& のパターン

始めにRustの x && y の演算子の両辺はJavaScriptやC/C++のような曖昧な表現は出来なく、 bool しか受け入れてくれません。
そして、Rustにおける x&&&y という式は x&&(&y) と解釈され、 y の参照を作り x と論理AND演算を行う命令となります。
true && (&false) という式はRustでは型が合っていないのと、暗黙の型変換もないのでコンパイルエラーになります。
x も参照で持って &true && (&false) で演算するしか選択肢がないですが、この演算も下記の様にコンパイルエラーが発生します。

main.rs
fn main() {
    // let compile_error = 1 && 1;
    let x = &true;
    let y = false;
    assert_eq!(x&&&y, false);
}
error[E0308]: mismatched types
 --> src/main.rs:5:16
  |
5 |     assert_eq!(x&&&y, false);
  |                ^
  |                |
  |                expected `bool`, found `&bool`
  |                help: consider dereferencing the borrow: `*x`

error[E0308]: mismatched types
 --> src/main.rs:5:19
  |
5 |     assert_eq!(x&&&y, false);
  |                   ^^
  |                   |
  |                   expected `bool`, found `&bool`
  |                   help: consider removing the borrow: `y`

すなわちこのパターンは出来ないことになります。
理由は単純にコンパイラーが &bool && (&bool) に対応していないからです。
Rustでは一部の記述パターンでは暗黙の参照外しがありますが、このパターンでは起きません。

*** のパターン

最後に x***y のパターンですが、Rustでは x*(*(*y)) と解釈されます。
*y は参照外しなので純粋に y&&y とすれば解決出来そうです。

main.rs
fn main() {
    let z = &&10;
    assert_eq!(10***z, 100);
}

今度はちゃんとコンパイルされ、参照が外されて、最後には 10 * 10 = 100 という式が成り立ちました。

今回は無理矢理感がありますが、y = &&value; x***y だけ成立するという希少なケースでしたので、
Rustで+++は許されない+ ++も許されない、 &&&も許されないけど***は(一部のケースで)許されるという結果になりました。

知識や記述の間違いがあればご指摘いただけれると嬉しいです。