斯卡拉案例类问题

时间:2009-10-05 16:16:54

标签: class scala case

关于'::'案例类我有两个问题。

::可以用作

case head :: tail => ...

它是如何工作的?意思是,Scala用于将List实例与:: case类匹配的流程究竟是什么?鉴于我有一个MyClass类,使用运算符op,我可以创建一个名为op的case类,我可以将其用作:

case foo op bar => ....

4 个答案:

答案 0 :(得分:5)

     scala> abstract class Stack {
     |     def push(n :Int):Stack
     | }
      defined class Stack

     scala> final case class push(st :Stack,hd :Int) extends Stack {
     |     override def push(n :Int):Stack = new push(this,n)
     | }
     defined class push

     scala> object NullStack extends Stack {
     |     override def push(n :Int):Stack = new push(null,n)
     | }
     defined module NullStack

     scala> val s = NullStack.push(1).push(2)
     s: Stack = push(push(null,1),2)

     scala> def test(s :Stack) = s match { case st push i => println(st +"push " + i) }
     test: (Stack)Unit

     scala> test(s)
     push(null,1)push 2

答案 1 :(得分:3)

详情见Programming in Scala第301页,关于List s上的模式匹配。

  

“cons”模式x :: xs是中缀的特例   运作模式。你已经知道了,当被视为表达时,   中缀操作等同于方法调用。对于模式,规则   不同:当看作模式时,中间操作如p op q   相当于op(p, q)。   也就是说,中缀运算符op被视为构造函数模式。   特别是,x :: xs等cons模式被视为::(x, xs)。   这暗示应该有一个名为::的类与模式对应   构造函数。确实有这样一个阶级。   它名为scala.::,正是构建非空列表的类。

答案 2 :(得分:2)

实际上,::是案例类的事实只是答案的一半。这在模式匹配中起作用的原因是对象::有一个提取器,它是在定义案例类时自动生成的。方便的是,::。unapply返回一个List,因为:: extends List。但是,如果您想对列表使用相同的技巧,则无法扩展List,因为它是 final 。你可以做的是使用适当的unapply方法定义一个对象,该方法具有预期的返回签名。例如,要匹配列表的 last 元素,您可以执行以下操作:

object ::> {def unapply[A] (l: List[A]) = Some( (l.init, l.last) )}

List(1, 2, 3) match {
  case _ ::> last => println(last)
}

(1 to 9).toList match {
  case List(1, 2, 3, 4, 5, 6, 7, 8) ::> 9 => "woah!"
}
(1 to 9).toList match {
  case List(1, 2, 3, 4, 5, 6, 7) ::> 8 ::> 9 => "w00t!"
}

提取器必须返回一个Option,它包含两个解构元素的元组。

答案 3 :(得分:0)

eed3si9n引用的文字在p。 “Scala编程”(第1版)的PDF版本中的331