2015-04-08 3 views
0

В приведенном ниже коде у меня есть главный актер, который поддерживает массив, и он создает дочерний актер, который создает массив и отправляет его обратно внутри сообщения, которое затем я хочу объединить в массив, который - утверждает главный актер. Я хотел сохранить общие сообщения, чтобы он мог работать для любого типа массива.Akka Объединение массивов из общих сообщений

object ActorMain { 

    case class addThese[T](len: Int, content: T) 

} 

class ActorMain extends Actor { 

    import ActorMain._ 
    import ReceivingActor._ 

    var myArray: Array[Double] = Array.empty 

    val child = context.actorOf(Props[ReceivingActor], "child") 

    child ! addThese(6, 5.0) 


    def receive = { 

    case result(plusOne) => { 

     myArray ++= plusOne 

    } 
    } 

} 


object ReceivingActor { 

    case class result[T](el: Array[T]) 

} 

class ReceivingActor extends Actor { 

    import ActorMain._ 

    import ReceivingActor._ 

    def receive = { 
    case addThese(len, content) => { 

     val res = Array.fill(len)(content) 

     sender ! result(res) 

    } 
    } 

} 

ошибка возникает при конкатенации myArray ++= plusOne. Это создает ошибку, поскольку plusOne имеет тип Any. Я попытался заменить эту строку myArray ++= plusOne.asInstanceOf[Array[Double]], но это дает ошибку java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [D. Есть ли способ сделать это, сохраняя при этом общие сообщения? Кажется, должен быть способ, чтобы главный актер знал точный тип массива, который он получает в сообщении, но я не знаю, возможно ли это, если сообщение является общим,

ответ

1

Вы может сделать

case result(plusOne: Array[Double]) => { 
    myArray ++= plusOne 
} 
case result(plusOne: Array[Object]) => ... 

Обратите внимание, что Array является единственным универсальным типом, для которого он работает, как это.

It seems as though there needs to be a way for the main actor to know the exact type of the array that it is receiving in the message

Точный тип вы отправка и получение является Array[Object] (записывается в виде [Ljava.lang.Object в сообщении исключения), поскольку content имеет тип Object (Any в Scala, но в конце концов, как Object в JVM).

+0

Это дает мне ошибку '' 'Ошибка: (23, 26) scrutinee несовместим с типом шаблона; найдено: Array [Double] required: Array [Any] Примечание: Двойной <: Любой, но класс Array инвариантен по типу T. Возможно, вы захотите исследовать шаблон подстановки, такой как '_ <: Any'. (SLS 3.2.10) case result (plusOne: Array [Double]) => {'' ' ^ – user1893354

+0

А, справа. Вы можете обойти это, используя результат класса case (el: Array [_]) ', где' Array [_] 'означает« Array произвольного типа ».или листинг' plusOne' '' Array [_] 'before сопоставление по типу. Не обязательно хорошая идея в целом, но в этом случае вы все равно не теряете безопасность типов. –

2

Как насчет параметризации myArray как массива [T]? Вам нужно будет параметризовать ActorMain и ReceivingActor соответственно.

Еще одна хорошая вещь - посыпать более явным типом информации. Вывод типа велик, когда выбивает новый код, но явные типы могут быть очень полезны при решении таких проблем. Если вы используете явные типы, вы бы использовали Array.fill [Double], Array.fill [Object] или Array.fill [T]?

Смежные вопросы