この記事は Scala Advent Calendar 2021 の15日目の記事です。
昨日は ryuhei ishibashi さんの Scalaで一番easyな構成を考えた(autowireの紹介) でした。
はじめに
- ずっとJavaをメインに開発してて、その後にScala(2.11くらい)を使うようになってスマートで書きやすいなと感動していた。
- ただ、列挙型はJavaのenumが使いやすくて、Scalaは標準のものが使い辛く毎回自分で実装したりと不満に感じていた。
- Scala3のenumがどうなったか公式を参考に使ってみる。
Scala3のenum
基本の書き方
enum Item:
case Pen, Eraser, Note
scala> Item.Pen
val res: Item = Pen
ここはどの言語でも大体同じ。
引数を持つ場合
enum Item(val price: Int):
case Pen extends Item(200)
case Eraser extends Item(300)
case Note extends Item(500)
scala> Item.Pen.price
val res: Int = 200
引数を持つenumもJavaのように書ける。
enumに標準で実装されているメソッドたち
scala> Item.Pen.ordinal
val res: Int = 0
scala> Item.fromOrdinal(0)
val res: Item = Pen
scala> Item.valueOf("Note")
val res: Item = Note
scala> Item.values
val res: Array[Item] = Array(Pen, Eraser, Note)
使用機会の多そうなvaluesが標準実装されているのが嬉しい。
valueOfを上手く使えば逆引きメソッドを作る手間も省けそう。
enumにメソッドを持たせる
enum Item(val price: Int):
private val DiscountRate = 0.2
def getDiscountPrice = price * (1 - DiscountRate)
case Pen extends Item(200)
case Eraser extends Item(300)
case Note extends Item(500)
end Item
scala> Item.Pen.getDiscountPrice
val res: Double = 160.0
メソッドも問題なく持たせられた。
enumのコンパニオンオブジェクトを作成する
object Item:
def getPairDiscountPrice = (Pen.price + Eraser.price) * 0.3
end Item
scala> Item.getPairDiscountPrice
val res8: Double = 150.0
コンパニオンオブジェクトも問題なく作成できた。
まとめ
- Scala3のenumは使いやすい、もうenumを作る際に悩まくて良さそう。