複数の種類のアクターが同じテンプレートに基づいている Akka ベースのアクター システムがあります。これは、これらのアクターが応答値のタイプによってのみ異なるという事実によるものです。例えば:
final case class Request(data: Any)
final case class Response(data: Any)
abstract class ActorTemplate[T] extends Actor {
def dataFunction: PartialFunction[Any, T]
def respond(data: T): Response
def receive: Receive = {
case Request(data) if dataFunction.isDefinedAt(data) =>
sender ! respond(dataFunction(data))
}
}
部分関数には型消去を回避する方法があり、単純化できません
def receive: Receive = {
case Request(data: T) =>
sender ! respond(data)
同時にif dataFunction.isDefinedAt(data)
、パターンにガードを付けることを強いられますが、私はそれがあまり好きではありません。
明示的な保護を回避する手段はありますか?
私が今のところ見つけた唯一の方法は、愚かなエクストラクタを導入することです:
object DataExtractor {
def unapply(data: Any): Option[T] =
if (dataFunction.isDefinedAt(data)) Some(dataFunction(data)) else None
}
def receive: Receive = {
case Request(DataExtractor(data) =>
sender ! respond(data)
しかし、標準ライブラリのどこかですでに行われているのでしょうか? または、コレクションメソッドに似た他の方法があるかもしれませんcollect
が、マッチングのためですか?
結論
いくつかの考えの後、extractor オブジェクトに戻り、@ pagoda_5b の提案の助けを借りてそれを特性に移動しました。
trait PFExtract[T] {
object PF {
def unapply(any: Any)(implicit pf: PartialFunction[Any, T]): Option[T] =
pf.lift(any)
}
}