【问题标题】:Scala - not a case class nor does it have method .unapplyScala - 不是案例类,也没有方法 .unapply
【发布时间】:2017-06-23 08:16:11
【问题描述】:

我对 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
    }

我收到以下错误:

错误: object Number 不是 case 类,也没有 unapply/unapplySeq 成员

错误:未找到:值总和

如何解决它们?提前致谢

【问题讨论】:

标签: scala intellij-idea case unapply


【解决方案1】:

在 Scala 中,case class 就像 class 具有额外的好处 + 一些其他属性。

对于普通班级,

class A(i: Int, s: String)

你不能这样创建它的实例,

val a = A(5, "five")   // this will not work

您必须使用new 来创建新实例。

val a = new A(5, "five")

现在假设我们有case class

case class B(i: Int, s: String)

我们可以像这样创建一个新的 B 实例,

val b = B(5, "five")

这与case class 一起工作的原因是因为case class 有一个自动创建的伴随对象,它提供了几个实用程序,包括applyunapply 方法。

所以,val b = B(5, "five") 这个用法实际上是val b = B.apply(5, "five")。而这里的B 不是class B,而是伴侣object B,它实际上是apply 方法。

类似地,Scala 模式匹配使用伴随对象提供的 unapplyunapplySeq 用于 SeqLike 模式)方法。因此,普通的 class 实例不适用于模式匹配。

假设您出于某种特定原因想要定义 class 而不是 case class 但仍想将它们与模式匹配等一起使用,您可以自己为其伴随对象提供所需的方法。

class C(val i: Int, val 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")
} 

另外,由于您是学习 Scala 的新手,您应该阅读http://danielwestheide.com/scala/neophytes.html,这可能是任何 Scala 初学者的最佳资源。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-13
    • 1970-01-01
    • 2018-12-10
    • 1970-01-01
    • 1970-01-01
    • 2019-03-06
    • 1970-01-01
    相关资源
    最近更新 更多