在case语句中间不适用的对象

时间:2017-01-16 20:47:37

标签: scala

scala> object Test {
         def unapply[L,R](v: (L, R)) = Some(v)
       }
defined object Test

scala> (1, 2) match {
         case 1 Test 2 => println("First")
         case Test((1, 2)) => println("Second")
         case _ => println("Third")
       }
First

有人可以解释为什么在元组的两个值之间使用对象的第一个案例是什么?

2 个答案:

答案 0 :(得分:3)

来自Scala Specifications 8.1.10

  

中缀操作模式
  中缀操作模式 p;op;q是构造函数或提取器模式op(p,q)的简写。

所以

case 1 Test 2 => println("First")

被重写为

case Test(1, 2) => println("First")

您可以在REPL中实际看到这一点,在该行的末尾添加//print并按<tab>两次:

scala> (1, 2) match { case 1 Test 2 => println("First") } //print
   scala.Tuple2.apply[Int, Int](1, 2) match {
     case $line10.$read.$iw.$iw.Test(1, 2) => scala.Predef.println("First")
   } // : Unit

答案 1 :(得分:1)

中缀操作模式 - 请参阅The Neophyte's Guide to Scala Part 1: Extractors

  

如果您按照Coursera的Scala课程学习,您了解到您可以使用cons运算符::或{{以类似于您创建它们的方式之一来构建列表和流。 1}},分别为:

#::
     

也许你想知道为什么这是可能的。答案是,作为我们迄今为止看到的提取器模式符号的替代方法,Scala还允许将提取器用于中缀表示法。因此,不是编写val xs = 58 #:: 43 #:: 93 #:: Stream.empty xs match { case first #:: second #:: _ => first - second case _ => -1 } ,而e(p1, p2)是提取器,而ep1是要从给定数据结构中提取的参数,它总是可以写{ {1}}

     

...我们的p2提取器也可用于读取p1 e p2的模式。但是,这不是你在实践中会做的事情。中缀操作模式的使用仅建议用于确实应该像运算符一样读取的提取器,这对于PremiumUsername PremiumUser score的cons运算符是正确的,但对于我们的List提取器肯定不行。