0Pricing
Scala for Backend Engineering & Functional Programming · レッスン

Scala 3 の enum

新しいenum構文

「Scala 3 の enum」はCoddyKit上の無料Scala for Backend Engineering & Functional Programmingレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはScala for Backend Engineering & Functional Programming学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Scala for Backend Engineering & Functional Programmingコースには全4レッスンが含まれています。

新しいenumキーワード

Scala 3には、第一級のenum構造が追加されました。Scala 2で使われていた、冗長なsealed traitとcase objectの組み合わせを簡潔な構文に置き換えます。

  • 各caseはenum型の値になります。
  • コンパイラーが便利なヘルパーを自動生成します。
enum Color:
  case Red, Green, Blue

object Main:
  def main(args: Array[String]): Unit =
    println(Color.Red)

すべての値を列挙する

すべての単純なenumには、すべてのcaseを含む配列valuesと、名前で検索するvalueOfを備えたコンパニオンが生成されます。

enum Color:
  case Red, Green, Blue

object Main:
  def main(args: Array[String]): Unit =
    Color.values.foreach(println)
    println(Color.valueOf("Green"))

序数と名前

各enum値には、0から始まる位置を表すordinalと、case名を使って生成されるtoStringがあります。

enum Color:
  case Red, Green, Blue

object Main:
  def main(args: Array[String]): Unit =
    println(Color.Blue.ordinal)
    println(Color.Red.ordinal)

パラメーター付きenum

enumのcaseにはコンストラクターパラメーターを指定でき、各値に関連データを持たせられます。RGBコードや惑星の質量などの定数を格納するのに便利です。

enum Planet(val mass: Double):
  case Earth extends Planet(5.97e24)
  case Mars  extends Planet(6.42e23)

object Main:
  def main(args: Array[String]): Unit =
    println(Planet.Earth.mass)
    println(Planet.Mars.mass)

enumのメソッド

enum本体の内部にメソッドを定義できます。クラスのメソッドと同様に、すべての値で利用できます。

enum Direction:
  case North, South, East, West
  def opposite: Direction = this match
    case North => South
    case South => North
    case East  => West
    case West  => East

object Main:
  def main(args: Array[String]): Unit =
    println(Direction.North.opposite)

ジェネリックADT enum

enumはジェネリックにしてパラメーター化できるため、代数的データ型をモデル化できます。ここでは簡略化したOption型を示します。

enum Maybe[+A]:
  case Just(value: A)
  case Nothing

object Main:
  def main(args: Array[String]): Unit =
    val a: Maybe[Int] = Maybe.Just(42)
    println(a)

再帰的なADT enum

enumは再帰的な構造に適しています。二分木や連結リストを、caseの集合としてすっきり表現できます。

enum Tree[+A]:
  case Leaf(value: A)
  case Branch(left: Tree[A], right: Tree[A])

object Main:
  def main(args: Array[String]): Unit =
    val t = Tree.Branch(Tree.Leaf(1), Tree.Leaf(2))
    println(t)

enumのパターンマッチング

enumはsealedなので、コンパイラーがmatchの網羅性を検査できます。caseが欠けていると警告が表示されます。

enum Light:
  case Red, Yellow, Green

object Main:
  def action(l: Light): String = l match
    case Light.Red    => "stop"
    case Light.Yellow => "slow"
    case Light.Green  => "go"

  def main(args: Array[String]): Unit =
    println(action(Light.Green))

Java互換enum

scala.reflect.Enumから自動的に派生すると、extends java.lang.Enum相当の動作を追加できます。完全なJava相互運用が必要な場合は、enum X extends Enum[X]と記述します。ただし、ほとんどのコードでは、必要に応じてJavaとうまく相互運用できる通常の形式を使います。

enum Suit:
  case Hearts, Diamonds, Clubs, Spades

object Main:
  def main(args: Array[String]): Unit =
    println(Suit.values.length)
    println(Suit.Spades.ordinal)

フィールドとメソッドの組み合わせ

パラメーター付きcaseと共通メソッドを組み合わせて、豊かなドメインモデルを構築できます。

enum Currency(val symbol: String):
  case USD extends Currency("$")
  case EUR extends Currency("\u20ac")
  def format(amount: Double): String = s"$symbol$amount"

object Main:
  def main(args: Array[String]): Unit =
    println(Currency.USD.format(9.99))

enumを使う場面

選択肢の集合が限定されている場合や、代数的データ型を扱う場合はenumを使いましょう。

  • 通常の列挙には単純なcase。
  • ADTやsum typeにはパラメーター付きcase。
  • 網羅性チェックが自動で行われるため、安全にリファクタリングできます。
enum Result[+E, +A]:
  case Ok(value: A)
  case Err(error: E)

object Main:
  def main(args: Array[String]): Unit =
    val r: Result[String, Int] = Result.Ok(7)
    println(r)

確認問題

Scala 3のenumについて理解度を確認しましょう。

まとめ

Scala 3のenumについて学びました。

  • 簡潔なenumが、sealed traitのボイラープレートを置き換えます。
  • 単純なenumにはvalues、valueOf、ordinalが生成されます。
  • caseには関連データ用のパラメーターを指定できます。
  • ジェネリックenumと再帰的enumでADTをモデル化できます。
  • sealedであるため、網羅的なパターンマッチングが可能です。
enum Weekday:
  case Mon, Tue, Wed, Thu, Fri
  def isStart: Boolean = this == Mon

object Main:
  def main(args: Array[String]): Unit =
    println(Weekday.Mon.isStart)
    println(Weekday.values.length)

よくある質問

「Scala 3 の enum」レッスンは無料ですか?

はい。「Scala 3 の enum」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Scala for Backend Engineering & Functional Programmingコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Scala for Backend Engineering & Functional Programmingコースには全4レッスンが含まれています。

「Scala 3 の enum」で何を学びますか?

新しいenum構文 ブラウザで直接実行するハンズオンコードでScala for Backend Engineering & Functional Programmingを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Scala for Backend Engineering & Functional Programmingを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのScala for Backend Engineering & Functional Programmingは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「Scala 3 の enum」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このScala for Backend Engineering & Functional Programmingレッスンでコードを書いて実行できますか?

はい。すべてのScala for Backend Engineering & Functional Programmingレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 重要なインデント
  2. Scala 3 の enum
  3. Opaque Types
  4. Union型とIntersection型
← Scala for Backend Engineering & Functional Programmingに戻る