MeWrite Docs

Scala: MatchError

Scalaでパターンマッチが網羅的でない場合のエラー

概要

Scalaのパターンマッチで、与えられた値がどのケースにも一致しない場合に発生するエラーです。

エラーメッセージ

scala.MatchError: someValue (of class SomeClass)

原因

  1. 網羅的でないパターンマッチ: すべてのケースをカバーしていない
  2. sealed traitの拡張: 新しいサブクラスを追加したがパターンを更新していない
  3. Optionのアンラップ: Some/Noneの両方をハンドルしていない

解決策

1. デフォルトケースを追加

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// 悪い例
val result = value match {
  case 1 => "one"
  case 2 => "two"
}  // 3以上でMatchError

// 良い例
val result = value match {
  case 1 => "one"
  case 2 => "two"
  case _ => "other"  // デフォルトケース
}

2. sealed trait で網羅性チェック

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
sealed trait Color
case object Red extends Color
case object Green extends Color
case object Blue extends Color

// コンパイラが警告を出す(網羅的でない)
def describe(color: Color): String = color match {
  case Red => "赤"
  case Green => "緑"
  // Blueがない!コンパイル時に警告
}

// 良い例
def describe(color: Color): String = color match {
  case Red => "赤"
  case Green => "緑"
  case Blue => "青"
}

3. Option を安全に処理

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// 悪い例
val Some(value) = maybeValue  // NoneでMatchError

// 良い例:パターンマッチ
maybeValue match {
  case Some(value) => println(value)
  case None => println("値なし")
}

// または getOrElse
val value = maybeValue.getOrElse("デフォルト")

// または fold
val result = maybeValue.fold("値なし")(v => s"値: $v")

4. Either を安全に処理

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// 悪い例
val Right(value) = eitherValue  // LeftでMatchError

// 良い例
eitherValue match {
  case Right(value) => println(s"成功: $value")
  case Left(error) => println(s"失敗: $error")
}

// または fold
val result = eitherValue.fold(
  error => s"失敗: $error",
  value => s"成功: $value"
)

5. Try を安全に処理

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import scala.util.{Try, Success, Failure}

// 悪い例
val Success(value) = tryValue  // FailureでMatchError

// 良い例
tryValue match {
  case Success(value) => println(value)
  case Failure(exception) => println(exception.getMessage)
}

// または recover
val result = tryValue.recover {
  case e: Exception => "デフォルト"
}.get

6. コンパイラ警告を有効化

1
2
3
4
5
// build.sbt
scalacOptions ++= Seq(
  "-Wunused:all",
  "-Xlint:all"
)

7. 部分関数を明示的に使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// 部分関数として定義
val handler: PartialFunction[Int, String] = {
  case 1 => "one"
  case 2 => "two"
}

// isDefinedAtで事前チェック
if (handler.isDefinedAt(value)) {
  handler(value)
} else {
  "不明"
}

// または applyOrElse
handler.applyOrElse(value, (_: Int) => "不明")

よくある間違い

  • 列挙型に新しい値を追加したが全てのmatchを更新していない
  • case classの抽出でフィールドがnullの場合を考慮していない
  • Listのパターンマッチで空リストを考慮していない

Scala の他のエラー

最終更新: 2025-12-09