Актеры и черты параллелизма в Scala - PullRequest
2 голосов
/ 14 июля 2011

Ребята, я новичок в Scala и пытаюсь что-то выяснить.Я немного возился с чертами характера, и мне очень нравится их способность «смешивать» функциональность и интерфейс.Я также возился с параллелизмом и актерами, и мне очень нравится возможность легко моделировать сложные сложные параллельные системы.

Проблема, с которой я столкнулся, заключается в том, что я не могу найти шаблон для объединенияоба мира.Что я действительно ищу, так это использую черты, чтобы определить, на какие типы сообщений отвечает Актер, что позволяет использовать разные ответы в иерархиях наследования.

Итак, для использования примера симулятора поля битвы: у меня есть симуляторы, которыечерты.Все объекты на поле битвы - симуляторы, и симуляторы должны ответить на «Пинг», отправив «Понг» - вот и все.Мне нужна черта IFF, которая позволит симулятору идентифицировать себя как друга или врага отправителя сообщения.Другая черта должна быть Mobile, что означает, что симулятор может двигаться и должен отвечать на сообщения, сообщающие симулятору о его новом назначении.

Как вы можете видеть, у меня может быть: class Tank extends Actor with Simulant with IFF with Mobile, но у меня может быть что-токак барьер, например class Barrier extends Actor with Simulant.

То, что я еще не смог сделать, - это создать правильную комбинацию act() методов, циклов, реакций и т. д., чтобы сделать этот сценарий возможным.Короче говоря, возможно ли «смешивать в реакторах сообщений» или Scala ограничивает меня выбором актеров с одним наследованием или миксинами без актеров?

Спасибо!

Ответы [ 2 ]

2 голосов
/ 14 июля 2011

Как насчет этого?

trait Simulant {
  def body: PartialFunction[Any, Unit] = {
    case Ping => reply(Pong)
  }

  def act = loop { react(body) }
}

trait IFF extends Simulant {
  override def body = super.body orElse {
    case FriendOrFoe => ...
  }
}

trait Mobile extends Simulant {
  override def body = super.body orElse {
    case Move(direction) => ...
  }
}

РЕДАКТИРОВАТЬ: Я только что попробовал это, и он прекрасно для меня:

aromanov@alexey-desktop:~$ scala
Welcome to Scala version 2.9.0.1 (OpenJDK Client VM, Java 1.6.0_22).
Type in expressions to have them evaluated.
Type :help for more information.

scala> object A {
     | import scala.actors.Actor
     | trait Simulant extends Actor {
     |   def body: PartialFunction[Any, Unit] = {
     |     case Ping => reply(Pong)
     |   }
     | 
     |   def act = loop { react(body) }
     | }
     | 
     | trait IFF extends Simulant {
     |   override def body = super.body orElse {
     |     case FriendOrFoe => {}  
     |   }
     | }
     | 
     | trait Mobile extends Simulant {
     |   override def body = super.body orElse {
     |     case Move(direction) => {}
     |   }
     | }
     | 
     | class Foo extends Actor with Simulant with IFF with Mobile
     | 
     | object Ping
     | object Pong
     | object FriendOrFoe
     | case class Move(direction: Int)
     | }
defined module A

С другой стороны, это не похожена самом деле работа : когда я заменяю case Ping => println("pinged"), я не вижу этого:

scala> (new A.Foo) ! A.Ping

scala>
0 голосов
/ 22 июля 2011

Я написал сообщение в блоге об этой проблеме и компромиссе, который нашел для ее решения.

http://www.kotancode.com/2011/07/19/traits-multiple-inheritance-and-actors-in-scala/

...