E108: Unapply Invalid Return Type
E108: Unapply Invalid Return Type (unapply 반환 타입이 잘못됨)
추출자의 unapply 또는 unapplySeq 메서드의 반환 타입이 유효하지 않을 때 나오는 에러예요.
본문
추출자로 사용하려면 unapply 메서드가 다음 중 하나에 해당하는 타입을 반환해야 해요.
isEmpty: Boolean과get: S멤버를 가진 타입 (보통Option[S])BooleanProduct(예:Tuple2[T1, T2])
예시
object MyExtractor:
def unapply(s: String): String = s
def example(s: String) = s match
case MyExtractor(_) => "ok"
case _ => "no match"
에러 메시지
-- [E108] Declaration Error: example.scala:5:18 --------------------------------
5 | case MyExtractor(_) => "ok"
| ^^^^^^^^^^^^^^
| String is not a valid result type of an unapply method of an extractor.
|-----------------------------------------------------------------------------
| Explanation (enabled by `-explain`)
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
| To be used as an extractor, an unapply method has to return a type that either:
| - has members isEmpty: Boolean and get: S (usually an Option[S])
| - is a Boolean
| - is a Product (like a Tuple2[T1, T2]) of arity i with i >= 1, and has members _1 to _i
|
| See: https://docs.scala-lang.org/scala3/reference/changed-features/pattern-matching.html#fixed-arity-extractors
|
| Examples:
|
| class A(val i: Int)
|
| object B {
| def unapply(a: A): Option[Int] = Some(a.i)
| }
|
| object C {
| def unapply(a: A): Boolean = a.i == 2
| }
|
| object D {
| def unapply(a: A): (Int, Int) = (a.i, a.i)
| }
|
| object Test {
| def test(a: A) = a match {
| case B(1) => 1
| case a @ C() => 2
| case D(3, 3) => 3
| }
| }
|
-----------------------------------------------------------------------------
해결 방법
용도에 따라 Option, Boolean, 또는 튜플을 반환하도록 바꾸면 돼요.
// Return Option[T] for single value extraction
object MyExtractor:
def unapply(s: String): Option[String] = Some(s)
def example(s: String) = s match
case MyExtractor(x) => x
case _ => "no match"
// Or return Boolean for test-only extraction
object IsEmpty:
def unapply(s: String): Boolean = s.isEmpty
def example(s: String) = s match
case IsEmpty() => "empty"
case _ => "not empty"
// Or return a tuple for multiple values
object Split:
def unapply(s: String): Option[(String, String)] =
val mid = s.length / 2
Some((s.take(mid), s.drop(mid)))
def example(s: String) = s match
case Split(a, b) => s"$a | $b"
case _ => "no match"
더 알아보기
- 고정 개수 추출자(fixed-arity extractor)에 대한 설명은 Scala 3 Reference의 패턴 매치 문서를 참고해요.