Scala - не случайный класс и не имеет метода.unapply
Я новичок в Scala и получил несколько нерешенных проблем со следующим кодом:
object exprs{
println("Welcome to the Scala worksheet")
def show(e: Expr): String = e match {
case Number(x) => x.toString
case Sum(l, r) => show(l) + " + " + show(r)
}
show(Sum(Number(1), Number(44)))
}
trait Expr {
def isNumber: Boolean
def isSum: Boolean
def numValue: Int
def leftOp: Expr
def rightOp: Expr
def eval: Int = this match {
case Number(n) => n
case Sum(e1, e2) => e1.eval + e2.eval
}
}
class Number(n: Int) extends Expr {
override def isNumber: Boolean = true
override def isSum: Boolean = false
override def numValue: Int = n
override def leftOp: Expr = throw new Error("Number.leftOp")
override def rightOp: Expr = throw new Error("Number.rightOp")
}
class Sum(e1: Expr, e2: Expr) extends Expr {
override def isNumber: Boolean = false
override def isSum: Boolean = true
override def numValue: Int = e1.eval + e2.eval
override def leftOp: Expr = e1
override def rightOp: Expr = e2
}
Я получаю следующие ошибки:
Ошибка: объект Number не является классом case и не имеет члена unapply/unapplySeq
Ошибка: не найдено: значение Sum
Как их решить? заранее спасибо
1 ответ
В Скала case class
похожи class
with extra goodies + some other properties.
For a normal class,
class A(i: Int, s: String)
You can not create its instance like this,
val a = A(5, "five") // this will not work
Вам придется использовать new
to create new instance.
val a = new A(5, "five")
Now lets say we have case class
,
case class B(i: Int, s: String)
We can create a new instance of B like this,
val b = B(5, "five")
Причина, по которой это работает case class
это потому что case class
have an auto-created companion objects with them, which provides several utilities including an apply
а также unapply
метод.
So, this usage val b = B(5, "five")
на самом деле val b = B.apply(5, "five")
, И здесь B
это не class B
but the companion object B
which is actually provieds apply
метод.
Similarly Scala pattern matching uses the unapply
(unapplySeq
for SeqLike patterns) methods provided by companion object. And hence normal class
instances do not work with pattern matching.
Lets say you wanted to defined a class
и не case class
for some specific reason but still want to use them with pattern-matching etc, you can provide its companion object with the required methods by yourselves.
class C(i: Int, s: String) {
}
object C {
def apply(i: Int, s: String) = new C(i, s)
def unapply(c: C) = Some((c.i, c.s))
}
// now you can use any of the following to create instances,
val c1 = new C(5, "five")
val c2 = C.apply(5, "five")
val c3 = C(5, "five")
// you can also use pattern matching,
c1 match {
case C(i, s) => println(s"C with i = $i and s = $s")
}
c2 match {
case C(i, s) => println(s"C with i = $i and s = $s")
}
Also, as you are new to learning Scala you should read http://danielwestheide.com/scala/neophytes.html which is probably the best resource for any Scala beginner.