Scala设计帮助,抽象类或特征上的模式匹配

时间:2013-06-01 23:47:34

标签: scala inheritance pattern-matching traits

编辑:我重写了我的问题以澄清并包含我想要实现的目标。

我正在构建一个使用Akka发送消息的系统。我正在使用一些小型服务来构建它。我有一个共享核心库,其中所有消息都作为案例类驻留。这些是我服务之间的合同。

我希望能做的是以下内容,但是我在抽象类消息的模式匹配中遇到编译错误:

case class Source( serviceId: String, time: String )
case class Credentials( tenantId:String, userId: String )
sealed abstract class Message( credentials:Credentials, sources: Vector[Source] )
trait FormEvent
trait MailEvent

case class FetchQuestion( questionId: String, credentials:Credentials, sources: Vector[Source] ) extends Message( credentials, sources ) with FormEvent
case class MailQuestion( questionId: String, credentials: Credentials, sources: Vector[Sources]) extends Message( credentials, sources ) with MailEvent

def route( msg:Message, tenantId: String, sources: Vector[Source] ) = msg match {
  case fe:FormEvent => s"form message for $tenantId with sources $sources."
  case me:MailEvent => s"mail message for $tenantId with sources $sources."
}

// Emulated Akka Receive, compilation error when matching.
def receive( a: Any ) = a match {
  case msg@Message( credentials, srs ) => route( msg.copy( sources = (srs :+ Source( "routing", "justnow" ) ) ), credentials.tenantId, srs) 
}

因此,模式匹配的契约似乎与案例类紧密结合,我需要采取哪些步骤来创建一个行为类似案例类的超类?


这是与提取器相同的示例。

case class Source( serviceId: String, time: String )
case class Credentials( tenantId:String, userId: String )
case class Trail(credentials: Credentials, sources: Vector[Source] )
trait Message {
  def trail: Trail
}

object Message {
  def unapply( msg: Message ) = Option( msg.trail ) 
}

trait FormEvent
trait MailEvent

case class FetchQuestion( questionId: String, trail:Trail ) extends Message with FormEvent
case class MailQuestion( questionId: String, trail:Trail ) extends Message with MailEvent

def route( msg:Message, tenantId: String, newSources: Vector[Source] ) = msg match {
  case fe:FormEvent => s"form message $msg for $tenantId with sources $newSources."
  case me:MailEvent => s"mail message $msg for $tenantId with sources $newSources."
}

// Emulated Akka Receive, compilation error when matching.
def receive( a: Any ) = a match {
  case msg@Message( Trail( Credentials( tenantId, _ ), srs ) ) => route( msg, tenantId, (srs :+ Source( "routing", "justnow" ) ) ) 
}

val fq = FetchQuestion( "question1", Trail( Credentials( "tenant", "user"), Vector( Source( "service1", "before" ) ) ) )

receive( fq )

1 个答案:

答案 0 :(得分:0)

您正在寻找的是extractors (unapply, unapplySeq)

但不是实现我会建议简化你的设计。您的多层继承方法太过混乱,我认为没有任何实际需要。


摆脱抽象类至少使你的继承模式统一。但是,您的设计存在问题,而且您需要过早优化。

首先,你必须在正确的方法中找到自己对这些特定情况的模式匹配,然后才能找到适合它的解决方案,反之亦然。不要试图解决您尚未面对的问题,并专注于您的实际问题。在大多数情况下,您会发现这些优化没有任何实际需要,或者您的应用程序到那时会发生很大变化,整个优化问题将会过时。因此,只有在必要时才开始简单并变得更加复杂。