我有一个案例类
case class ~[a,b](_1:a, _2:b)
当我想做pattetn匹配时
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))
如何呈现?按什么规则?
答案 0 :(得分: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
关键字,case class ~
会被unary_~
遮蔽,这会给出参数的按位否定。类似~ 2
的表达式在内部评估为unary_~(2)
,~ ("a", 1)
的情况也是如此 - 但除非您在该元组上定义unary_~
,否则会出错。使用new
关键字,您建议编译器显式查找具有该名称的类,因此不会混淆。
(从技术上讲,你可以使用$tilde("a", 1)
作为case class ~
的内部名称来解决这个问题,但由于这是一个编译器细节,你可能不应该依赖它。)
2&amp; 3)Scala Language Specification中引用了右关联性。 “中缀操作”部分
操作员的关联性由操作员的最后一个字符决定。以冒号':'结尾的运算符是右关联的。所有其他运算符都是左关联的。
顺便说一句,右关联性是允许使用Nil
创建列表的技巧。 (Nil
为空List
,并定义了右关联连接运算符::
。)
val l: List[Int] = 1 :: 2 :: 3 :: Nil
评估如下
val l: List[Int] = (1 :: (2 :: (3 :: Nil)))
或更确切地说,自3 :: Nil
≡Nil.::(3)
以来,
val l: List[Int] = ( ( Nil.::(3) ).::(2) ).::(1)