E189: Extractor Not Found — 추출자를 찾을 수 없음

E189: Extractor Not Found — 추출자를 찾을 수 없음

unapply 또는 unapplySeq 메서드를 가진 객체를 가리키지 않는 이름으로 추출자 패턴을 사용할 때 발생하는 에러예요.

출처: Scala 3 Reference

본문

패턴 매칭의 추출자(extractor)는 값을 분해(deconstruct)할 수 있는 unapplyunapplySeq 메서드를 가진 객체를 필요로 해요. 케이스 클래스와 enum case는 이러한 추출자를 자동으로 제공해줘요.

좀 더 자세한 설명 (Longer explanation)

패턴 안의 name(...) 형태의 적용은 unapplyunapplySeq 메서드를 정의한 추출자를 가리킬 수 있어요. 예시:

object split:
  def unapply(x: String) =
    val (leading, trailing) = x.splitAt(x.length / 2)
    Some((leading, trailing))

val split(fst, snd) = "HiHo"

추출자 패턴 split(fst, snd)는 우변 "HiHo"의 앞부분 "Hi"fst로, 뒷부분 "Ho"snd로 정의해요. 케이스 클래스와 enum case는 클래스나 enum case의 이름으로 추출자를 암시적으로 정의해요.

예시 (Example)

def example(): Unit =
  val s(): String = "hello"

에러 (Error)

-- [E189] Not Found Error: example.scala:2:6 -----------------------------------
2 |  val s(): String = "hello"
  |      ^
  |      no pattern match extractor named s was found
  |-----------------------------------------------------------------------------
  | Explanation (enabled by `-explain`)
  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  | An application s(...) in a pattern can refer to an extractor
  | which defines an unapply or unapplySeq method. Example:
  |
  |   object split:
  |     def unapply(x: String) =
  |       val (leading, trailing) = x.splitAt(x.length / 2)
  |       Some((leading, trailing))
  |
  |   val split(fst, snd) = "HiHo"
  |
  | The extractor pattern `split(fst, snd)` defines `fst` as the first half "Hi" and
  | `snd` as the second half "Ho" of the right hand side "HiHo". Case classes and
  | enum cases implicitly define extractors with the name of the class or enum case.
  | Here, no extractor named s was found, so the pattern could not be typed.
   -----------------------------------------------------------------------------

해결 방법 (Solution)

괄호 없이 단순한 값 바인딩을 사용하세요:

def example(): Unit =
  val s: String = "hello"
  println(s)

추출자가 필요하다면 하나를 정의하고 match에서 사용하세요:

object MyString:
  def unapply(s: String): Option[String] = Some(s)

def example(): Unit =
  "hello" match
    case MyString(s) => println(s)

더 알아보기

패턴의 name(...)unapply/unapplySeq를 가진 추출자를 가리켜야 해요. 그런 객체가 없다면 이 에러가 나요.