Scala:基于自定义类型的模式匹配

时间:2018-02-14 03:05:11

标签: scala

如你所知,关于语言的一个好处就是模式匹配的方式:

val frontman ="Mick Jagger"

frontman match {
  case "Mick Jagger" => "Rolling Stones"
} 

然而,基于基本类型(IntBooleanStringFloat等)的匹配对我来说不是一个非常干净的方式。有没有更好的方法来创建我自己的类型,它们拥有基本类型的值, 然后我根据它进行模式计算?

显然我可以拥有val rollingStonesFrontman = "Mick Jagger",然后根据它进行匹配;但是希望有一种更可维护的方法。

为什么它不可维护:它不可维护,因为对于未来的其他开发人员来说,更好地制作模型,然后在模式中使用它在整个申请中匹配。

初始尝试:我可以分解基本类型值的最简洁方法,并在模式匹配中使用它:

trait Band{
  val frontman: String
}

object RollingStones extends Band{
  override val frontman = "Mick Jagger"
}

val toBeMatched = "Mick Jagger"

toBeMatched match{
  case RollingStones.frontman => println("We got the Rolling Stones singer!")
}

是否有更清晰的方式来编写上述代码?

1 个答案:

答案 0 :(得分:0)

是的,请在此处查看“匹配案例类”:http://docs.scala-lang.org/tour/pattern-matching.html#matching-on-case-classes

从那里:

(time_t)

更新:如果没有更具体的例子,很难知道你在寻找什么......也许这就是:

(char *)&customers[0].customer_creation_date - (char *) customers) / sizeof (char)

更新,稍微清洁:

abstract class Notification
case class Email(sender: String, title: String, body: String) extends Notification
case class SMS(caller: String, message: String) extends Notification
case class VoiceRecording(contactName: String, link: String) extends Notification

def showNotification(notification: Notification): String = {
  notification match {
    case Email(email, title, _) =>
      s"You got an email from $email with title: $title"
    case SMS(number, message) =>
      s"You got an SMS from $number! Message: $message"
    case VoiceRecording(name, link) =>
      s"you received a Voice Recording from $name! Click the link to hear it: $link"
  }
}

不需要if-guard,因为您可以在模式匹配中直接使用标识符。但它要求它是稳定的标识符(例如:val,object,literal ... not var或def)。所以原来的trait Frontman case object MickJagger extends Frontman trait Band case object RollingStones extends Band frontman match { case MickJagger => RollingStones } 不起作用。如果标识符只是一个没有对象前缀的abstract class Band (val frontman: String) object RollingStones extends Band(frontman = "Mick Jagger") val toBeMatched = "Mick Jagger" toBeMatched match { // no need for if guard case RollingStones.frontman => println("We got the Rolling Stones singer!") } ,那么它需要反引号来区分它与模式变量。