当用作表达式时,当用作模式时,h::t被设计成两种不同的东西。这是完全有意义的,因为当在表达式中使用它时,我们希望将::方法应用于参数为h的t,即t.$colon$colon(h);而当它用于匹配情况时,我们希望将它识别为$colon$colon(h,t),即case类模式。
在一种无聊的好奇心中,我想知道是什么原因导致了这两种不同的解释。对于表达式,我理解::是一种右关联方法,但是在其他情况下,它是如何从h::t到$colon$colon(h,t)的呢?
编辑:添加源代码来说明这两种不同的上下文:
def decode(xs: List[Int]): Unit =
xs match {
case Nil =>
case h :: t => println(h::t); decode(t)
}发布于 2018-01-06 06:24:22
正如jwvh所指出的,您的问题不明确,允许各种解释。无论如何,我会试着回答一些更明显的问题:
:: 诉 $colon$colon
与许多传统语言不同,Scala允许定义自定义运算符,包括几乎任何符号,如":“。另一方面,Scala被编译到其他一些目标平台(如JVM),这些平台不允许在方法名称中使用这种符号。要解决这一问题,编译器需要自动将“禁止”的符号转换为一些罕见但有效的序列。$colon就是:的这样一个序列。因此,::转换为$colon$colon。
Infix表示法
友好的自定义操作符的另一个要点是允许不确定符号,它也适用于任何只使用一个参数的方法,而不仅仅是操作符。例如,您还可以编写list map func,它将被翻译成list.map(func)
模式匹配
用于模式匹配的Scala设计是显式可扩展的。这意味着您可以编写代码,以便模式匹配将适用于您的自定义类。您需要编写的代码是一个)方法 (更简单的示例请参见本指南 )。此外,对于case classes,编译器会自动生成适当的unapply。如果您查看代码,您可能会发现scala.collection.immutable.::实际上是一个case class。
https://stackoverflow.com/questions/48122833
复制相似问题