0
object micro extends App {

  sealed trait FuncExpr

  sealed trait FuncSpecialize

  sealed case class Func(i:Int) extends FuncExpr
  sealed case class Cube(b:Boolean) extends FuncSpecialize

  object Cube {
    def unapply(arg:Func) : Option[Boolean] = arg match {
      case Func(i) if i == 42 => Some(true)
      case _ => None
    }
  }

  val x : FuncSpecialize = Cube(true)
  x match {
    case Cube(b) => println("Success")
  }
}

这是一个最小化的示例,其中我尝试为案例类 Cube 实现自定义 unapply 方法以及默认的 unapply 方法。但是,如果尝试对 xi 进行模式匹配,则会收到以下错误消息,因为 Func 和 FuncSpezialize 是完全不同的类型:

Error:(19, 10) cannot resolve overloaded unapply
    case Cube(b) => println("Success")
Error:(19, 10) overloaded method value unapply with alternatives:
  (x$0: micro.Cube)Option[Boolean] <and>
  (arg: micro.Func)Option[Boolean]
 cannot be applied to (micro.FuncSpecialize)
    case Cube(b) => println("Success") 

任何想法,为什么会这样?

4

1 回答 1

1

由于Cube是一个案例类,编译器unapply为其生成

  object Cube {
    // auto-generated
    def unapply(arg: Cube): Option[Boolean] = Some(arg.b)

    // custom
    def unapply(arg:Func) : Option[Boolean] = arg match {
      case Func(i) if i == 42 => Some(true)
      case _ => None
    }
  }

现在,当您尝试匹配模式时

  val x : FuncSpecialize = Cube(true)
  x match {
    case Cube(b) => println("Success")
  }

这实际上是一个电话Cube.unapply(x)。您不能将任何unapply方法应用于xtype FuncSpecialize

于 2019-05-09T15:19:37.643 回答