6

我有一个案例课

case class ~[a,b](_1:a, _2:b)

当我想做模式匹配时

new ~("a", 25) match{
  case "a" ~ 25 =>
}

我可以这样使用它,因为"a" ~ 25~("a", 25)是等价的。但如果我想new ~("a", new ~("b", 25))通过{case "a" ~ "b" ~ 25 => }麻烦开始匹配。我知道这些陈述并不等同。那么,如何 new ~("a", new ~("b", 25))呈现呢?依据什么规则?

4

1 回答 1

10

这有效:

new ~("a", new ~("b", 25)) match {
  case "a" ~ ("b" ~ 25) =>
}

因此,您必须将括号与它们在初始子句中的方式相同。否则波浪号是左关联的,因此模式的类型会不同,它不会编译。

case "a" ~ "b" ~ 25

是相同的

case ("a" ~ "b") ~ 25

在你的情况下这是错误的。

附录

您可以通过将冒号作为类/方法名称中的最后一个字符来获得右关联性。以下编译和匹配不带括号(您可以删除编译器,new因为编译器不会再被 混淆$tilde$colon):

case class ~:[a,b](_1:a, _2:b)

~:("a", ~:("b", 25)) match {
  case "a" ~: "b" ~: 25 =>
}

回应

1) 如果没有new关键字, thecase class ~会被遮蔽,unary_~从而给出参数的按位否定。像这样的表达式~ 2在内部被评估,unary_~(2)同样的情况也适用于~ ("a", 1)- 但是除非你unary_~在那个元组上定义,否则这将给出一个错误。使用new关键字,您建议编译器显式查找具有该名称的类,这样就不会混淆。(从技术上讲,您可以通过使用$tilde("a", 1)which 的内部名称来解决此问题case class ~,但由于这是编译器细节,您可能不应该依赖它。)

2&3) Scala Language Specification中引用了右关联性。“中缀操作”部分</p>

运算符的关联性由运算符的最后一个字符决定。以冒号 ':' 结尾的运算符是右结合的。所有其他运算符都是左结合的。

顺便说一句,右关联性是允许使用Nil. (Nil是空的List,并且定义了右关联连接运算符::。)

val l: List[Int] = 1 :: 2 :: 3 :: Nil

评估如下

val l: List[Int] = (1 :: (2 :: (3 :: Nil)))

或者,更准确地说,由于3 :: NilNil.::(3),如

val l: List[Int] = ( ( Nil.::(3) ).::(2) ).::(1)
于 2010-07-14T12:46:03.697 回答