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

ガードと束縛

マッチ時の条件を扱います。

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

ガードとは

ガードは、ifを使ってケースにブール条件を追加するものです。パターンに一致し、かつガードが真の場合にだけケースがマッチします。

ガードを使うと、値に基づいて1つのパターンをより細かいケースに分けられます。

ifガードの追加

パターンの後にガードを記述します。case n if n > 0 =>のように書きます。条件が偽の場合、次のケースへマッチングが続きます。

object Main {
  def sign(n: Int): String = n match {
    case x if x > 0 => "positive"
    case x if x < 0 => "negative"
    case _          => "zero"
  }
  def main(args: Array[String]): Unit = {
    println(sign(5))
    println(sign(-3))
    println(sign(0))
  }
}

バインドしてからガード

ガードでは、パターンでバインドした名前を参照できます。これにより、マッチした値の特性をテストできます。

object Main {
  def fizz(n: Int): String = n match {
    case x if x % 15 == 0 => "FizzBuzz"
    case x if x % 3 == 0  => "Fizz"
    case x if x % 5 == 0  => "Buzz"
    case x                => x.toString
  }
  def main(args: Array[String]): Unit = {
    println(fizz(15))
    println(fizz(9))
    println(fizz(7))
  }
}

範囲に対するガード

ガードは、リテラルパターンでは直接表現できない範囲の指定に最適です。

object Main {
  def band(score: Int): String = score match {
    case s if s >= 90 => "A"
    case s if s >= 80 => "B"
    case s if s >= 70 => "C"
    case _            => "F"
  }
  def main(args: Array[String]): Unit = {
    println(band(95))
    println(band(83))
    println(band(60))
  }
}

@によるパターンバインド

@記号を使うと、構造のパターンマッチングを行いながら、マッチした値全体を名前にバインドできます。

ここでのwhole @ patternは、patternにマッチし、そのマッチした値をwholeと呼ぶ、という意味です。

object Main {
  def main(args: Array[String]): Unit = {
    val x: Any = 7
    val msg = x match {
      case n @ (_: Int) => s"int value is $n"
      case _            => "other"
    }
    println(msg)
  }
}

コレクション内でのバインド

@によるバインドは、構造化されたパターンで特に便利です。たとえば、リストの先頭を調べながらリスト全体を取得できます。

object Main {
  def describe(xs: List[Int]): String = xs match {
    case all @ (first :: _) => s"starts with $first, full = $all"
    case Nil                => "empty"
  }
  def main(args: Array[String]): Unit = {
    println(describe(List(1, 2, 3)))
    println(describe(Nil))
  }
}

型パターンとガードの組み合わせ

型パターンとガードを組み合わせられます。まず型がチェックされ、次にブール条件がチェックされます。

object Main {
  def label(x: Any): String = x match {
    case s: String if s.length > 3 => "long string"
    case s: String                 => "short string"
    case _                         => "not a string"
  }
  def main(args: Array[String]): Unit = {
    println(label("hello"))
    println(label("hi"))
    println(label(42))
  }
}

複数の条件

ガードは単なるブール式なので、&&や||を使って条件を組み合わせられます。

object Main {
  def category(age: Int): String = age match {
    case a if a >= 13 && a <= 19 => "teen"
    case a if a < 13             => "child"
    case _                       => "adult"
  }
  def main(args: Array[String]): Unit = {
    println(category(15))
    println(category(8))
    println(category(40))
  }
}

ガードはフォールスルーしない

パターンに一致してもガードが偽の場合、Scalaは同じパターンの次のガードではなく、次のケースへ進みます。

すべてのガードに失敗した値を、後続のケースで処理できるようにしてください。

object Main {
  def test(n: Int): String = n match {
    case x if x > 100 => "big"
    case x            => s"not big: $x"
  }
  def main(args: Array[String]): Unit = {
    println(test(200))
    println(test(5))
  }
}

なぜガードとバインドを使うのか

ガードと@によるバインドを組み合わせると、パターンマッチングを柔軟に表現できます。

  • ガードで範囲や割り切れるかどうかなどの条件を追加できる
  • @で分解しながら値全体を取得できる
  • 分岐ロジックを簡潔で読みやすく保てる

まとめて使う

この例では、値をバインドし、ガードをチェックし、フォールバックを用意します。

object Main {
  def temp(c: Int): String = c match {
    case t if t >= 30 => s"hot ($t)"
    case t if t >= 15 => s"mild ($t)"
    case t            => s"cold ($t)"
  }
  def main(args: Array[String]): Unit = {
    println(temp(35))
    println(temp(20))
    println(temp(5))
  }
}

理解度チェック

ガードとバインドについての理解度を確認しましょう。

まとめ

マッチングをより細かく絞り込む方法を学びました。

  • ガードは、パターンの後に置くif条件
  • ガードが偽の場合、マッチングは次のケースへ進む
  • @演算子は、構造を分解しながら値全体をバインドする
  • ガードは型パターンやブール演算子と組み合わせられる

よくある質問

「ガードと束縛」レッスンは無料ですか?

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

「ガードと束縛」で何を学びますか?

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

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

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

「ガードと束縛」レッスンにはどのくらい時間がかかりますか?

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

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

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

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

  1. match 式
  2. 型と値のマッチング
  3. ガードと束縛
  4. デコンストラクション
← Scala for Backend Engineering & Functional Programmingに戻る