在 Intellij IDEA 中导航角色系统的代码
Navigating the code of an actor system in Intellij IDEA
我使用 IntelliJ IDEA,但问题可能与其他 IDE 相关。有一种使用 Ctrl + 单击来导航代码的好方法。它从方法调用跳转到方法声明。它确实提高了生产力。
Actor 系统基于消息传递。使用 Scala 的 Akka 示例:
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
)会更合适。
您如何在 actor 之间导航代码?
我认为这通常是不可能的,因为参与者可以在运行时更改其行为,包括它可以处理的消息——与可以静态索引的方法相反。例如,可以根据 actor 状态计算接收函数:
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"
}
}
现在 actor 会根据之前处理的消息以不同的方式处理消息。这只是一个简单的例子 - 甚至可以从外部接收到实际的演员行为!
case class Behavior(receive: Actor.Receive)
class MyActor extends Actor {
def receive = {
case Behavior(r) => context.become(r)
}
}
另一个更大的困难是你通常有一个 ActorRef
,你用 !
向它发送消息。这个 ActorRef
与包含消息处理逻辑的 actor class 没有静态连接 - 它是用 Props
实例化的,它可以使用任意代码来确定应该使用哪个 actor class :
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 提交功能请求。
不完美,但对消息类型使用“查找用法”(Alt+F7) 可能会有帮助。为此,您可能必须先导航到声明类型 (Ctrl+Shift+B)
不知道有没有简单的方法可以为组合创建快捷方式
另一个想法是使用 Structural Search,它可能能够找到表达式之类的东西,匹配 class 名称 ...
根据自己的喜好创建模板后,您就可以record a macro
我使用 IntelliJ IDEA,但问题可能与其他 IDE 相关。有一种使用 Ctrl + 单击来导航代码的好方法。它从方法调用跳转到方法声明。它确实提高了生产力。
Actor 系统基于消息传递。使用 Scala 的 Akka 示例:
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
)会更合适。
您如何在 actor 之间导航代码?
我认为这通常是不可能的,因为参与者可以在运行时更改其行为,包括它可以处理的消息——与可以静态索引的方法相反。例如,可以根据 actor 状态计算接收函数:
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"
}
}
现在 actor 会根据之前处理的消息以不同的方式处理消息。这只是一个简单的例子 - 甚至可以从外部接收到实际的演员行为!
case class Behavior(receive: Actor.Receive)
class MyActor extends Actor {
def receive = {
case Behavior(r) => context.become(r)
}
}
另一个更大的困难是你通常有一个 ActorRef
,你用 !
向它发送消息。这个 ActorRef
与包含消息处理逻辑的 actor class 没有静态连接 - 它是用 Props
实例化的,它可以使用任意代码来确定应该使用哪个 actor class :
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 提交功能请求。
不完美,但对消息类型使用“查找用法”(Alt+F7) 可能会有帮助。为此,您可能必须先导航到声明类型 (Ctrl+Shift+B)
不知道有没有简单的方法可以为组合创建快捷方式
另一个想法是使用 Structural Search,它可能能够找到表达式之类的东西,匹配 class 名称 ...
根据自己的喜好创建模板后,您就可以record a macro