Ответ 1
Вы можете использовать super[T]
для ссылки на элементы определенных суперклассов/признаков.
Например:
trait IntActor extends Actor {
def receive = {
case i: Int => println("Int!")
}
}
trait StringActor extends Actor {
def receive = {
case s: String => println("String!")
}
}
class IntOrString extends Actor with IntActor with StringActor {
override def receive = super[IntActor].receive orElse super[StringActor].receive
}
val a = actorOf[IntOrString].start
a ! 5 //prints Int!
a ! "Hello" //prints String!
Edit:
В ответ на комментарий Hugo, вот решение, которое позволяет вам составлять микшины без необходимости вручную подключать их вместе. По сути, он включает базовый признак с изменяемым List[Receive]
, и каждый смешанный признак вызывает метод для добавления своего собственного приема в список.
trait ComposableActor extends Actor {
private var receives: List[Receive] = List()
protected def registerReceive(receive: Receive) {
receives = receive :: receives
}
def receive = receives reduce {_ orElse _}
}
trait IntActor extends ComposableActor {
registerReceive {
case i: Int => println("Int!")
}
}
trait StringActor extends ComposableActor {
registerReceive {
case s: String => println("String!")
}
}
val a = actorOf(new ComposableActor with IntActor with StringActor).start
a ! 5 //prints Int!
a ! "test" //prints String!
Единственное, о чем нужно помнить, это то, что порядок получения не должен быть важен, поскольку вы не сможете легко предсказать, какой из них является первым в цепочке, хотя вы можете решить это, используя изменяемый хэш файл вместо списка.