简体   繁体   English

如何对具有多个参数列表的 class 进行模式匹配?

[英]How to pattern match a class with multiple argument lists?

Consider this class:考虑这个 class:

class DateTime(year: Int, month: Int, day: Int)(hour: Int, minute: Int, second: Int)

how would the unapply method look like, if I would like to match against something like:如果我想匹配以下内容, unapply方法会是什么样子:

dt match {
  case DateTime(2012, 12, 12)(12, _, _) => // December 12th 2012, 12 o'clock
  /* ... */
}

I tried this:我试过这个:

def unapply(dt: DateTime) = 
  Some((dt.year, dt.month, dt.day),(dt.hour, dt.minute, dt.second))

But that didn't really work.但这并没有真正奏效。

Case classes match (and do their other nifty things) only on the first set of parameters:案例类仅在第一组参数上匹配(并做其他漂亮的事情):

scala> case class A(i: Int)(j: Int) { }
defined class A

scala> A(5)(4) match { case A(5) => "Hi" }
res14: java.lang.String = Hi

scala> A(5)(4) == A(5)(9)
res15: Boolean = true

If it's not a case class, you can define the unapply to be anything you want, so it's really up to the implementer of the class.如果不是 class 的情况,您可以将 unapply 定义为您想要的任何内容,因此这实际上取决于 class 的实现者。 By default, there is no unapply, so you can match only on the type.默认情况下,没有 unapply,因此您只能在类型上进行匹配。

If you want to use the nifty case class features including being able to match and do equality on everything, but have some sort of division, you could nest case classes:如果您想使用漂亮的案例 class 功能,包括能够对所有内容进行匹配和相等,但有某种划分,您可以嵌套案例类:

case class Time(hour: Int, minute: Int, second: Int) { }
case class Date(year: Int, month: Int, day: Int) { }
case class DateTime(date: Date, time: Time) { }

scala> val dt = DateTime(Date(2011,5,27), Time(15,21,50))
scala> dt match { case DateTime(Date(2011,_,_),Time(h,m,50)) => println(h + ":" + m) }
15:21

Just to build on Rex's answer, not only can you only pattern match on the first parameter block, but this behaviour is very much by design.只是以 Rex 的回答为基础,您不仅只能在第一个参数块上进行模式匹配,而且这种行为在很大程度上是设计使然。

The more interesting question is why case classes, as algebraic data types, even support multiple parameter lists...更有趣的问题是,为什么 case 类,作为代数数据类型,甚至支持多个参数列表......

There's no strong enough justification to add special behaviour for case classes, and multiple parameter lists turn out to be pretty useful.没有足够的理由为案例类添加特殊行为,并且多个参数列表非常有用。 In production code this facility is often only used to supply implicit arguments, which you quite naturally wouldn't want to pattern match.在生产代码中,此功能通常仅用于提供隐式 arguments,您很自然不希望对其进行模式匹配。

It probably didn't work because Scala has no comma operator, and you're returning Some((a,b),(x,y)) from the extractor.它可能不起作用,因为 Scala 没有逗号运算符,并且您从提取器返回Some((a,b),(x,y)) If you used Some(((a,b,c),(x,y,z))) instead (ie a Tuple2[Tuple3[A,B,C],Tuple3[X,Y,Z]] I think it would probably work.如果您使用Some(((a,b,c),(x,y,z)))代替(即Tuple2[Tuple3[A,B,C],Tuple3[X,Y,Z]]我认为可能会工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM