LoginSignup
6
2

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-07-15

そもそも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で+++は許されない+ ++も許されない、 &&&も許されないけど***は(一部のケースで)許されるという結果になりました。

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

6
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2