为什么我必须以unapply方法返回some

时间:2017-10-23 20:00:55

标签: scala

如果我在Some方法中不使用unapply,为什么以下代码无效?

scala> object T {
     | def unapply(i:Int) = (i+1,i+2) //Some not used, I get error
     | }
defined object T

scala> 1 match {
     | case T(x,y) => println(x,y)
     | }
<console>:14: error: an unapply result must have a member `def isEmpty: Boolean
       case T(x,y) => println(x,y)
            ^

scala> object T {
     | def unapply(i:Int) = Some(i+1,i+2) //Some used. No error
     | }
defined object T

scala> 1 match {
     | case T(x,y) => println(x,y)
     | }
(2,3)

阶&GT;

2 个答案:

答案 0 :(得分:8)

你不是。您必须返回具有isEmpty()方法和get()方法的内容。 Option提供了两者,这是一个方便的解决方案。

这是编译器知道匹配成功的方式。如果isEmpty()返回true,则匹配失败并尝试下一场比赛(如果有下一场比赛)。

答案 1 :(得分:0)

  val bob = new Person("bobby", 28)

  abstract class Wrapper[T] {
    def isEmpty: Boolean

    def get: T
  }

  object PersonWrapper {

    def unapply(arg: Person): Wrapper[String] = new Wrapper[String] {
      def isEmpty = false

      def get: String = arg.name
    }
  }

  println {
    bob match {
      case PersonWrapper(n) => s"name is $n"
    }
  }

输出:名字是鲍比

如果isEmpty设置为true,那么我们将得到scala.MatchError

换句话说,

  object even {
    def unapply(x: Int): Boolean = x % 2 == 0
  }

  object singleDigit {
    def unapply(x: Int): Boolean = x > -10 && x < 10
  }

  println {
    12 match {
      case singleDigit2() => s"single digit ...."
      case even2()        => s"even number......."
    }
  }

如果unapply方法返回false,我们将得到scala.MatchError