Class scala案例类问题

Class scala案例类问题,class,scala,case,Class,Scala,Case,关于“::”案例类,我有两个问题 ::可以用作 case head :: tail => ... 它是如何工作的?也就是说,Scala用于将列表实例与::case类匹配的确切流程是什么?假设我有一个类MyClass,带有运算符op,我可以创建一个名为op的case类,用作: case foo op bar => .... ?关于列表上的模式匹配,详细信息见第301页,共页 “cons”模式是中缀的特例 操作模式。你已经知道,当被看作一种表情时, 中缀操作相当于方法调用。对于模式,

关于“::”案例类,我有两个问题

::可以用作

case head :: tail => ...
它是如何工作的?也就是说,Scala用于将列表实例与::case类匹配的确切流程是什么?假设我有一个类MyClass,带有运算符op,我可以创建一个名为op的case类,用作:

case foo op bar => ....

关于
列表上的模式匹配,详细信息见第301页,共页

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


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

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!"
}

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

replice of,really.我的问题不仅仅是变量之间的“::”是怎么回事,还包括一个case类如何匹配另一个类的实例(原因是List#:::创建了::case类的实例)eed3si9n引用的文本位于第页。331在“Scala编程”(第1版)的PDF版本中,回答得很好!所以技巧是List#:::返回case类的实例::。我不认为unapply在这里应用scala>val l=List(1,2,3)l:List[Int]=List(1,2,3)scala>scala.:::::。unapply(l):6:错误:类型不匹配;发现:List[Int]required:::[?]val r=scala::(1,Nil)r::[Int]=List(1)scala>scala::.unapply(r)res7:Some[List[Int]=Some(List()),因此unapply仅在实际由case类构造时有效,而不是针对一般列表。case类创建的unapply没有什么特别之处。请注意,列表是抽象的,实际上任何非空列表都是scala的实例。::列表(1)。isInstanceOf[::[Int]],这意味着您在模式中匹配的实际上是scala的实例。::(除非它是Nil)。还请注意,只要只为以下对象重新定义unapply,列表的模式匹配就会中断:对象:{def unapply=false}
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!"
}