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

Sealed トレイト

閉じた階層構造です。

レッスン 2/413 ステップ

「Sealed トレイト」は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レッスンが含まれています。

Traitとは

traitはインターフェースに似たもので、ほかのクラスが拡張できる共通の型を宣言します。

traitを使うと、関連する型を1つのまとまりとしてグループ化できるため、それらを同じように扱えます。

基本的なTrait

traitでtraitを宣言し、クラスやオブジェクトでextendsします。

trait Shape
case class Circle(r: Double) extends Shape
case class Square(side: Double) extends Shape
object Main {
  def main(args: Array[String]): Unit = {
    val s: Shape = Circle(2.0)
    println(s)
  }
}

sealedとは

sealedなtraitは、同じファイルで宣言された型からのみ拡張できます。

これにより階層が閉じられるため、コンパイラーは存在し得るサブタイプの完全な一覧を把握できます。

sealed trait Color
case object Red extends Color
case object Green extends Color
case object Blue extends Color
object Main {
  def main(args: Array[String]): Unit = {
    val c: Color = Green
    println(c)
  }
}

バリアントとしてのCase Object

バリアントがデータを持たない場合は、case classではなくcase objectを使います。インスタンスは常に1つだけです。

列挙型のような値を表すのに最適です。

sealed trait Direction
case object North extends Direction
case object South extends Direction
object Main {
  def main(args: Array[String]): Unit = {
    val d: Direction = North
    println(d)
  }
}

オブジェクトとクラスの組み合わせ

sealed traitには、case objectのバリアント(データなし)とcase classのバリアント(データあり)の両方を定義できます。

sealed trait Event
case object Started extends Event
case class Failed(reason: String) extends Event
object Main {
  def main(args: Array[String]): Unit = {
    val e: Event = Failed("timeout")
    println(e)
  }
}

Sealed Traitに対するマッチング

traitに対してマッチングを行い、それぞれのバリアントを処理します。階層がsealedであるため、すべてのバリアントを網羅しているかコンパイラーが確認できます。

sealed trait Color
case object Red extends Color
case object Green extends Color
case object Blue extends Color
object Main {
  def hex(c: Color): String = c match {
    case Red   => "#FF0000"
    case Green => "#00FF00"
    case Blue  => "#0000FF"
  }
  def main(args: Array[String]): Unit = {
    println(hex(Green))
  }
}

コンパイラーの警告

sealed traitに対するmatchでバリアントを1つでも忘れると、コンパイラーが不足しているケースを警告します。

後から新しいバリアントを追加したときにも、これによってバグを見つけられます。詳しくは網羅的マッチングのレッスンで説明します。

Traitでメンバーを宣言する

traitでは、すべてのサブタイプで共有する、または実装が必要なメソッドやフィールドを宣言できます。

sealed trait Animal {
  def sound: String
}
case object Dog extends Animal { def sound = "Woof" }
case object Cat extends Animal { def sound = "Meow" }
object Main {
  def main(args: Array[String]): Unit = {
    println(Dog.sound)
    println(Cat.sound)
  }
}

なぜsealedなのか

traitをsealedにすると、次の利点があります。

  • 既知の、閉じたサブタイプ集合
  • matchでの網羅性チェック
  • バリアント追加時の、より安全なリファクタリング

Scalaでは、sealed traitとcase classを組み合わせて代数的データ型を構築します。

階層を利用する

関数はtrait型を受け取り、パターンマッチングによって任意のバリアントを処理できます。

sealed trait Payment
case class Cash(amount: Int) extends Payment
case class Card(number: String) extends Payment
object Main {
  def summary(p: Payment): String = p match {
    case Cash(a) => s"cash $a"
    case Card(n) => s"card ending ${n.takeRight(4)}"
  }
  def main(args: Array[String]): Unit = {
    println(summary(Cash(50)))
    println(summary(Card("123456789012")))
  }
}

すべてを組み合わせる

複数の種類のバリアントを持つsealed traitを、各ケースにマッチする関数で共有します。

sealed trait Result
case object Pending extends Result
case class Success(value: Int) extends Result
case class Error(msg: String) extends Result
object Main {
  def show(r: Result): String = r match {
    case Pending    => "waiting"
    case Success(v) => s"ok: $v"
    case Error(m)   => s"fail: $m"
  }
  def main(args: Array[String]): Unit = {
    List(Pending, Success(7), Error("boom")).foreach(r => println(show(r)))
  }
}

クイックチェック

sealed traitについての理解度を確認しましょう。

まとめ

sealed traitについて学びました。

  • traitは共通のスーパータイプを定義します
  • sealedはサブタイプを同じファイル内に限定します
  • データを持たないバリアントにはcase objectを、データを持つバリアントにはcase classを使います
  • sealedにすると、matchで網羅性をチェックできます
無料で開始

AI チューターと学ぶ Scala — 無料

ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。

コース
39
レッスン
143

よくある質問

「Sealed トレイト」レッスンは無料ですか?

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

「Sealed トレイト」で何を学びますか?

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

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

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

「Sealed トレイト」レッスンにはどのくらい時間がかかりますか?

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

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

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

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

  1. ケースクラス
  2. Sealed トレイト
  3. 代数的データ型
  4. 網羅的マッチング
← Scala for Backend Engineering & Functional Programmingに戻る