Навигация по коду актерской системы в Intellij IDEA
Я использую IntelliJ IDEA, но этот вопрос может касаться других IDE. Существует отличный способ навигации по коду с помощью Ctrl+ клик. От вызова метода он переходит к объявлению метода. Это действительно повышает производительность.
Системы акторов основаны на передаче сообщений. Пример в Акке со Скалой:
class MyMessage
object MyMessage
class MyActor1 extends Actor {
context.actorOf(Props[MyActor2]) ! MyMessage
}
class MyActor2 extends Actor {
def receive = {
case MyMessage =>
...
}
}
Есть ли способ в коде перемещаться между отправкой сообщения и получением сообщения?
Я имею в виду, нажав на !
приведет меня к определению !
метод в ScalaActorRef
, но это 99% шанс, что я этого не хочу. Переход к соответствующему методу приема (или, если возможно, для исправления регистра: case MyMessage
) было бы более уместным.
Как вы перемещаетесь по коду между актерами?
2 ответа
Я не думаю, что это вообще возможно, потому что субъект может изменить свое поведение во время выполнения, включая то, какие сообщения он может обрабатывать - в отличие от методов, которые могут быть статически проиндексированы. Например, функция приема может быть вычислена в зависимости от состояния актера:
class MyActor extends Actor {
var i = 0
def receive = firstReceive
def commonReceive = {
case Increment =>
i += 1
if (i % 3 == 0) context.become(firstReceive)
else context.become(secondReceive)
}
def firstReceive = commonReceive orElse {
case Ping =>
sender ! "zero"
}
def secondReceive = commonReceive orElse {
case Ping =>
sender ! "one or two"
}
}
Теперь актер обрабатывает сообщения по-разному, в зависимости от того, какие сообщения он обрабатывал раньше. И это только простой пример - реальное поведение актера может быть получено извне!
case class Behavior(receive: Actor.Receive)
class MyActor extends Actor {
def receive = {
case Behavior(r) => context.become(r)
}
}
Еще одна трудность, которая еще больше, заключается в том, что у вас обычно есть ActorRef
на который вы отправляете сообщения с !
, это ActorRef
не имеет статической связи с классом актера, который содержит логику обработки сообщений - он создается с Props
который может использовать произвольный код, чтобы определить, какой класс акторов следует использовать:
val r = new Random
val a = actorSystem.actorOf(Props(if (r.nextInt(100) > 50) new FirstActor else new SecondActor))
a ! Message // which handler should this declaration lead to?
Это делает поиск фактического обработчика сообщений практически невозможным.
Если вы считаете, что стоит поддерживать более простые случаи, например, тот, который вы указали, вы всегда можете отправить запрос на добавление функций в YouTrack.
Не идеально, но что может помочь, так это использовать Find Usage (Alt+F7) для типа сообщения. Для этого вам, вероятно, придется сначала перейти к объявлению типа (Ctrl+Shift+B)
Интересно, есть ли простой способ создать ярлык для комбинации?
Другой идеей было бы использовать Структурный поиск, который мог бы найти такие вещи, как выражения, которые совпадают с именем класса...
Как только вы создали шаблон по своему вкусу, вы можете записать макрос