kotlin の enum
2024/10/10
C/C++ には enum
がある。
私がやりがちなこれだが、他の言語では仕様としてできないことが多い。
#include <stdio.h>
int main(void)
{
enum {
First, Second, Third,
} part = First;
printf("part=%d\n", part);
part++;
printf("part=%d\n", part);
return 0;
}
C/C++ は enum
は整数型扱いになるので計算に使うことができる。対応できる一番小さい整数型にするとかだったか。
あと、デバッガでenum
型扱いにしてもらえるので値がちょっと見やすい。
それに慣れていたので思うところはないのだが、列挙型が計算できるってなんなのよ、と言われれば確かにそういう気もする。
Go言語にはないし、TypeScriptだと使わない方がよいとかあるし。
Kotlin にも enum
があるが同様に整数型扱いではない。
Kotlin の列挙型は enum class
という使い方になる。
これは OK だ。
出力は「First」である。
enum class Status {
First, Second, Third,
}
fun main() {
var status: Status = Status.First
println("$status")
}
ordinal
を付けると順番の整数値が取得できる。
こうすると出力は「1」である。
fun main() {
var status: Status = Status.Second
println("${status.ordinal}")
}
プライマリーコンストラクタにプロパティを付けて値付きで定義することもできる。
in enum型.entries
や enumValueOf(文字列)
のようなちょっと特殊な使い方ができる。
しかし status
にインクリメントしたり計算結果の代入はできない。
数値として使いたいなら数値型を使えばよいのだ。
それはわかっているのだが、状態を enum
型にして、次に進めるときは++
して、と考えてしまうのだ。呪いのようなものか。
あきらめて enum class
で計算無しに使うか、整数型にして const val
を使って #define
的なものを用意するのか?
整数値からenum
値に変換する関数を持たせることで対応する例があった。
How do I create an enum from an Int in Kotlin? - Stack Overflow
enum class Types(val value: Int) {
FOO(1),
BAR(2),
FOO_BAR(3);
companion object {
fun fromInt(value: Int) = Types.values().first { it.value == value }
}
}
fun main() {
var t = Types.fromInt(1)
println("t=${t}")
t = Types.fromInt(t.value+1)
println("t=${t}")
}
fromInt()
は何をやってるんでしょうね。。。
first() は集合型の先頭要素に関するものだが、it
とか使っているから後置ラムダ式というやつだろう。
inline fun <T> Array<out T>.first(
predicate: (T) -> Boolean
): T
その実装はこちらで、イテレータでぐるぐる回してラムダ式の中に書いた結果がtrue
であればそのときのT
をそのまま返す。
public inline fun <T> Array<out T>.first(predicate: (T) -> Boolean): T {
for (element in this) if (predicate(element)) return element
throw NoSuchElementException("Array contains no element matching the predicate.")
}
なるほどねぇ。
for
でぐるぐる回せばできるとは思ったが、まあそれしかないわな。
ちなみに対応する値を引数に与えない場合は NoSuchElementException
が発生する。
ただ、1行で書かれているから気付きにくいが、大した処理ではないとはいえループで回っている。
これをわざわざループで回して処理したいかと私は NO なのだが、一般的にはどうなんだろう。