enum の反転
◆ 2 つの要素の enum を反転する
◆ 1 から enum 値を引く
◆ 1 から enum 値を引く
enum Aim { in, out }
みたいな 2 つだけの enum ってそこそこ使いますよね
そんなときに今と逆の方を選びたいってこと 多いと思います
綺麗にかくなら if 文場合わけじゃなく拡張メソッドとかしたいですけど enum ごとに作るのはけっこう手間です
JavaScript で文字列の "1", "0" を反転した数値がほしい時のこういうのみたいに短く書けないかなー
> var strnum = "1"
> +!+strnum
0
> strnu = "0"
> +!+strnum
1
> +!+strnum
0
> strnu = "0"
> +!+strnum
1
と考えていて 短くスッキリ書ける方法を見つけました
> enum A { a, b }
> (A)(-~-(int)A.a)
b
> (A)(-~-(int)A.b)
a
> (A)(-~-(int)A.a)
b
> (A)(-~-(int)A.b)
a
スッキリかどうかは人によりますが 個人的にはけっこう気持ちのいい書き方です
簡単に解説すると enum の数値は指定なければ 0 から始まる連番なので 0 と 1 です
int キャストすると数値が取れるので 0, 1 にして反転 その後また enum にキャストして戻します
0, 1 反転が JavaScript みたいに +! でできればいいのですが そうはいかないので
-~- を使ってます
~ はビット反転なので ~(-1) は 0 で ~0 は -1 になります
これを使って 0, 1 反転してます
-~-
が顔に見えてくる辺りが好みです
引き算だとキャストいらなかった
0, 1 反転に -~- じゃなく引き算も使えましたが キャストいるなら大して差がないし 二項演算子の間にスペース入れたら -~- のほうが短いしと 思ってました(A)(-~-(int)A.a)
(A)(1 - (int)A.a)
(A)(1 - (int)A.a)
ですが キャストなしでできました
> enum A { a, b }
> 1 - A.a
b
> 1 - A.b
a
> 1 - A.a
b
> 1 - A.b
a
すごくシンプル!
int 型じゃなくて enum 型の方に合わされるんですね
でも -~- がなくなったのはちょっと残念