【问题标题】:Unable to resolve unapply无法解决 unapply
【发布时间】:2019-09-27 10:14:32
【问题描述】:
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 方法。但是,如果尝试对 x 进行模式匹配,我会收到以下错误消息,这是我不希望发生的,因为 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") 

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

【问题讨论】:

    标签: scala case-class unapply


    【解决方案1】:

    由于Cube是一个case类,编译器为其生成了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 方法应用于x 类型的FuncSpecialize

    【讨论】:

    • 如果我删除自定义 unapply 方法,但模式匹配工作正常。关于您的解释,这不应该也失败吗?谢谢
    • @TilmanZuckmantel 它不能正常工作。它编译但在运行时以MatchError 失败。
    • 如果我删除自定义取消应用,它会为我编译并打印成功。
    • @TilmanZuckmantel Cube 仍然是一个案例类。所以unapply还是由编译器生成的。
    猜你喜欢
    • 2018-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-11
    • 1970-01-01
    • 2016-03-30
    • 2018-04-21
    • 2019-06-24
    相关资源
    最近更新 更多