如何解释这个 FSM 示例的行为?

how to explain the behaviour of this FSM example?

我试图理解 akka FSM 模式,但在下面的示例中,我不明白为什么我没有得到与处理 -> 完成对应的打印。我的印刷品清楚地表明我已经完成了。有人可以启发我吗?

import akka.actor.{ActorRef, FSM}
import scala.concurrent.duration._
import akka.actor.Actor
import akka.actor.ActorSystem
import akka.actor.FSM.Event
import akka.actor.Props

object FSM2 extends App{
  val system = ActorSystem("test")
  val test = system.actorOf(Props[Test], "t")
  test ! Set("hello")
}

sealed trait State
case object idle extends State
case object processing extends State
case object complete extends State

sealed trait Data
case class Content(processing:Int) extends Data

class Test extends FSM[State, Data]{

  when(idle) {
    case Event(test:Set[String], _) => {
      goto(processing) using Content(test.size-1)
    }
 }
  when(processing, stateTimeout = 1 second) {
     case Event(StateTimeout, Content(count)) => {
     println(count)
     count match {
        case 0 => goto(complete) using Content(0)
        case _ => stay using Content(count)
     }
    }
  }
  when (complete, stateTimeout = 1 second) {
    case Event(StateTimeout, _) => {
      println("in complete")
      goto(idle) using Content(0)
    }
 }

  onTransition({
    case idle -> processing => {
    println("idle -> processing")
  }
  case processing -> complete => {
      println("processing -> complete")
  }
  })

  startWith(idle, Content(0))
  initialize()
}
output:
idle -> processing
idle -> processing
0
idle -> processing
in complete
idle -> processing

I thought this would be the expected output:

idle -> processing
0
idle -> processing
processing -> complete
in complete
(go back to idle with no print)

我写的一些其他代码表明它不执行模式匹配而是执行赋值。

如果我在 State 对象(Idle、Processing、Complete 和 Idle -> Processing 等)上使用大写字母,它会起作用。

主要问题是,case idle -> processing 与您的案例对象不匹配,但与任何东西都匹配,并将这些任何东西绑定到名称 idleprocessing。为了匹配那些 case 对象,你必须匹配一个稳定的标识符,这意味着要么以大写字母开头 case 对象(正如你已经观察到的那样),要么在你的匹配中用反引号包围它们:

case `idle` -> `processing`

考虑到这一点,应该清楚字符串 "idle -> processing" 是为每个状态转换打印的,而不仅仅是从空闲到处理的状态转换,您可以通过打印 println(s"$idle -> $processing") 来验证这一点.

output:
idle -> processing // triggered by initialize(), is actually idle -> idle
idle -> processing // the actual idle -> processing transition
0
idle -> processing // processing -> complete
in complete
idle -> processing // complete -> idle