Scala 在Intellij IDEA中导航参与者系统的代码

Scala 在Intellij IDEA中导航参与者系统的代码,scala,intellij-idea,akka,actor,code-navigation,Scala,Intellij Idea,Akka,Actor,Code Navigation,我使用IntelliJ IDEA,但问题可能与其他IDE有关。有一种很好的方法可以通过Ctrl+click导航代码。从方法调用跳到方法声明。它确实提高了生产力 Actor系统基于消息传递。使用Scala的Akka示例: class MyMessage object MyMessage class MyActor1 extends Actor { context.actorOf(Props[MyActor2]) ! MyMessage } class MyActor2 extends Ac

我使用IntelliJ IDEA,但问题可能与其他IDE有关。有一种很好的方法可以通过Ctrl+click导航代码。从方法调用跳到方法声明。它确实提高了生产力

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
中使用code>method,但我不希望出现这种情况的几率是99%。跳转到相应的接收方法(或者,如果可能,更正大小写:
case MyMessage
)更合适


如何在参与者之间导航代码?

我认为这在一般情况下是不可能的,因为参与者可以在运行时更改其行为,包括可以处理哪些消息,而不是可以静态索引的方法。例如,可以根据参与者状态计算接收函数:

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类没有静态连接-它通过
Props
实例化,可以使用任意代码来确定应该使用哪个actor类:

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?
这使得查找实际的消息处理程序几乎不可能


如果您认为支持更简单的案例(如您提供的案例)是值得的,那么您可以始终向提交功能请求。

我认为这通常是不可能的,因为参与者可以在运行时更改其行为,包括其可以处理的消息,而不是可以静态索引的方法。例如,可以根据参与者状态计算接收函数:

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类没有静态连接-它通过
Props
实例化,可以使用任意代码来确定应该使用哪个actor类:

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?
这使得查找实际的消息处理程序几乎不可能


如果您认为支持更简单的案例(如您提供的案例)是值得的,那么您可以随时向提交功能请求。

这并不完美,但对消息类型使用Find Usage(Alt+F7)可能会有所帮助。为此,您可能必须首先导航到类型声明(Ctrl+Shift+B)

我想知道是否有一种简单的方法可以为组合创建快捷方式

另一个想法是使用,它可能能够找到诸如expressions之类的内容,这些内容与类名匹配


一旦你创建了一个你喜欢的模板,你就可以对它进行改进,但是对消息类型使用Find Usage(Alt+F7)会有所帮助。为此,您可能必须首先导航到类型声明(Ctrl+Shift+B)

我想知道是否有一种简单的方法可以为组合创建快捷方式

另一个想法是使用,它可能能够找到诸如expressions之类的内容,这些内容与类名匹配


一旦你创建了一个你喜欢的模板,你就可以

你可能需要点击你正在使用的变量来访问演员类型!在(跳转到定义)上,点击道具的类型,并搜索receive方法的实现。正如其他人提到的,可能有多个。您可能需要通过点击您正在使用的变量来访问参与者类型!在(跳转到定义)上,点击道具的类型,并搜索receive方法的实现。正如其他人提到的,可能不止一个。