编辑:我重写了我的问题以澄清并包括我想要实现的目标。
我正在构建一个使用 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 )