2014/12/10 このエントリーをはてなブックマークに追加 はてなブックマーク - 【これは便利】知っててよかったKotlinのenum #ktac2014

【これは便利】知っててよかったKotlinのenum #ktac2014




https://matlabrecipes.comより引用





こちらはKotlinアドベントカレンダーの10日目の記事です。






versionはKotlin M8。2014/12/5現在、Kotlinはマイナーバージョンです。





M8バージョン:https://github.com/yyYank/sandbox/blob/master/Kotlin/WebDemo/M8/KolinEnumSample.kt



****2017 年追記 :
1.1.2バージョンhttps://github.com/yyYank/sandbox/blob/master/Kotlin/WebDemo/1.1.2/KolinEnumSample.kt
Kotlinのenumはいつのタイミングかは忘れましたが、 enumの書き方が変わりました。
宣言を簡単に記述出来るようになる言語変更です。M8バージョンと1.1.2バージョンを見比べてみてください!!





Javaのenumについて今日話題になっていたため、Kotlinのenumってどうなっているんだろう?
ということで今回調べてみました。





Kotlinの場合は「enum class クラス名」と宣言することでenumを定義できます。
こんな感じです。


enum class Direction { 
  NORTH
  SOUTH 
  WEST
  EAST
}







使えるメソッドはJavaとほぼ同等です。




name、toString、ordinal,equals,compareToなど。
== 演算子での比較も可能です。
switchではなく、Kotlinではwhenを使います。


  //==============================================
  // enumの持つ基本的なメソッド
  //==============================================  
  
  println(Direction.NORTH.name())
  println(Direction.NORTH.toString())
  println(Direction.SOUTH.ordinal())
  println(Direction.SOUTH.equals(Direction.NORTH))
  println(Direction.SOUTH.compareTo(Direction.NORTH))
  println(Direction.SOUTH == Direction.NORTH)
  
  
  
  //==============================================
  // whenでパターンマッチ
  //==============================================
  val d = Direction.SOUTH
  when(d) {
      Direction.NORTH -> println("north")
      Direction.SOUTH -> println("south")
      Direction.WEST -> println("west")
      Direction.EAST -> println("east")
      else -> println("else")
  }





もちろん、Stateパターンなども出来ます。

enum class ProtocolState {
  WAITING {
    override fun signal() = TALKING
  }

  TALKING {
    override fun signal() = WAITING
  }

  abstract fun signal(): ProtocolState
}









以下のように、状態管理が出来ます。

val state = ProtocolState.WAITING

println(state.signal()) // TALKING
println(state.signal()) // WAITING
println(state.signal()) // TALKING
println(state.signal()) // WAITING
println(state.signal()) // TALKING
println(state.signal()) // WAITING






詳しくはKotlinのenumのAPIリファレンスを参照してください。










ここまでだとあまりJavaと変わらないですね。
Kotlinだと便利なのはenumにパラメータを持たせるときです。






Javaで書くとしたらこうなります。


enum YEN{
    private int value;
    
    YEN(int rgb) {
        this.rgb = rgb;
    }
    
    public int getRgb(){
        return  this.rgb;
    }
    
    RED(0xFF0000),
    GREEN(0x00FF00),
    BLUE(0x0000FF);
}



これを、Kotlinで書くと・・・。
enum class Color(val rgb: Int) {
  RED : Color(0xFF0000)
  GREEN : Color(0x00FF00)
  BLUE : Color(0x0000FF)
}






かなりシンプルになっていますね。

また、Kotlinの場合、
enum自身からJavaでいうstreamと同等の処理が可能です(というと過言ですが)。
例えば、日本円の通貨をあらわすenumがあったとします。



enum class Yen(val price: Int) {
  十円硬貨 : Yen(10)
  百円硬貨 : Yen(100)
  千円札 : Yen(1000)
  一万円札 : Yen(10000)
}





この中で100円よりも大きい通貨だけを出力するというすると
Javaの場合はStream.ofやArrays.streamを利用する必要があります。

  //==============================================
  // Java lambda
  //==============================================
  Stream.of(Yen.values()).filter(x -> x.getPrice() > 100).forEach(System.out::println);




Kotlinの場合はこのようにenum自身からfilterを呼び出せます。
  //==============================================
  // Kotlin lambda
  //==============================================
  Yen.values().filter{it.price > 100}.forEach{println(it)}
  
  
  









全文はGitHubにアップしています。







いかがでしたでしょうか。
今回のポイントは以下2点です。


1.Kotlinは簡易にenumが記述できる。
2.enum自身からfilterやforEachなどが呼び出せる

Javaでもenumって地味な存在ではありますが、
そういう地味な奴は地味にめんどくさいのです。



Kotlinならめんどくさくない!




0 件のコメント:

コメントを投稿