Scala - Extractor Objects confusion

℡╲_俬逩灬. 提交于 2019-12-13 07:13:15

问题


I am kind of confused about extractor and its using. I read Scala document and meet that one

object Twice {
  def apply(x: Int): Int = x * 2
  def unapply(z: Int): Option[Int] = if (z%2 == 0) Some(z/2) else None
}
object TwiceTest extends App {
  val x = Twice(21)  // x = 42
  x match { case Twice(n) => Console.println(n) } // prints 21
}`

As the above code print out, when we call x match {case Twice(n) ..., it means Twice(n) --> Twice.unapply(n) --> Twice.unapply(42) and get Some(n/2) --> Some(42/2) and plug result into n again, print out 21

If I change "unapply" as follow: def unapply(z: Int): Option[Int] = if (z%2 == 0) Some(z - 2) else None

What I get from the console is 40

So, do I understand it right?


回答1:


it means Twice(n) --> Twice.unapply(n) --> Twice.unapply(42)

No, Twice(n) is a pattern (here; it can also be used as an expression, but with a different meaning), and Twice.unapply(n) is an expression. And it's an expression which makes no sense here, because you don't have a value for n yet! Twice.unapply(x) is called instead.

x match { case Twice(n) => ...expression_using_n; ...other cases } is basically the same as

Twice.unapply(x) match { 
  case Some(n) => ...expression_using_n
  case None => x match { ...other cases }
}

Or to remove circularity, since Some itself is an extractor object:

val unapplied = Twice.unapply(x)
if (unapplied.isDefined) {
  val n = unapplied.get
  ...expression_using_n
} else 
  x match { ...other cases }


来源:https://stackoverflow.com/questions/36859663/scala-extractor-objects-confusion

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!