2016-10-27 9 views
1

私はそこに簡単な解決策があることを知っています。しかし、私はそれを考えることはできません。"共有"パラメータ化タイプ

私は一般的なキューを持っています。それは、その中に含まれるものに型パラメータ化されたActorです。私は、同じ種類を強制する必要があるキューにデータを送信するためのメッセージクラス追加メッセージが必要です。

我々はこれを行うことができます

: ...

これに問題があることである:キュー[A]は、俳優{ ケースクラスは、[A](配列[A]の項目)を追加拡張し

クラスをQueueのインスタンスからAddのインスタンスを作成することができ、ActorRefだけを知っているクライアントはそのようなインスタンスを持たないでしょう。

AddをQueueの外に移動すると、その問題はなくなりますが、コンパイラはAddの型パラメータとQueueの型パラメータが何らかの形で関連していることを知らないのです。この2つのコレクションを組み合わせるには型キャストが必要です。

2つの無関係なクラスの型パラメータが関連していることをコンパイラに簡単に伝える方法はありますか?

+0

私はこれが俳優のタイプ無しに付属する制限だと思う。 – Thilo

+0

私はその考えを持っていました... –

答えて

0

あなたはQueue[A]俳優でAdd[_]メッセージを受信したときに、送信者は、俳優の種類を知らないとあなたは、キャスト/タイプチェックを行う必要がありますので、彼らが送ったことを強制することはできませんAdd[A]Add[B]

これはtype erasure

のそれは俳優の内側の種類に依存クラスとしてのメッセージを入れてもかなり厄介だから、あなたはそれが困難構築するために見つけることができますよう、厄介なことになるだろうではありません。

これは可能ですが、デザインを単純化する方がよいと思います。ここに行く:

import Queue.Add 
import akka.actor.{Actor, ActorSystem, Props} 
import scala.reflect.runtime.universe._ 

class Queue[A]()(implicit tt: TypeTag[A]) extends Actor { 

    override def receive = { 
    case [email protected] Add(items) if a.tpe.tpe <:< typeOf[A] => 
     println("added: " + items) 

    case other => 
     println("bad message: " + other) 
    } 
} 

object Queue { 
    case class Add[A](
    items: List[A])(
    implicit val tpe: TypeTag[A]) 
} 

object Main { 
    def main(args: Array[String]): Unit = { 

    val system = ActorSystem() 

    val stringQueue = system.actorOf(Props(new Queue[String]())) 

    stringQueue ! Add(List("a","b")) 
    stringQueue ! Add(List(1,2,3)) 
    } 
} 
+0

"送信者がアクターのタイプを知らないので、キュー[A]アクターでAdd [_]メッセージを受け取ったら、キャスト/タイプチェックを行う必要がありますだからAdd [A]を送り、Add [B]を送りつけることはできません。そうです、それが私の指摘でした。それがここの問題です。私はあなたの提案されたsolnをチェックアウトします - ありがとう。 –

関連する問題