【问题标题】:Akka Type mismatchAkka 类型不匹配
【发布时间】:2014-01-08 19:57:45
【问题描述】:

我是 akka 的初学者,我陷入了这个编译问题:

class MyActor extends Actor {
  def receive = {
    case Outer(operation, someInt, someBool) =>
      makeOperation(operation, someInt, someBool) 
  }    

  private def makeOperation(operation: Operation, someInt: Int, someBool: Boolean): Receive = {
    operation match {
      case MainOp(otherInt) =>
        if (someBool) {
          if (otherInt < someInt) {
            root ! makeMessage(...)
          } else if (otherInt > someInt) {
            root ! makeMessage(...) // <-  compilation error here
          } else {
            root ! makeMessage(...) // <-  compilation error here
          }
        } else {
          if (otherInt > someInt) {
            root ! makeMessage(...) // <-  compilation error here
          } else if (otherInt < someInt) {
            root ! makeMessage(...) // <-  compilation error here
          } else {
            root ! makeMessage(...) // <-  compilation error here
          }
        }
      case OtherOp1(...) => ???
      case OtherOp2(...) => ???
    }
  }
}

控制台显示的错误如下:

MyFile.scala:161: type mismatch;
  found   : Unit
  required: MyActor.this.Receive
     (which expands to)  PartialFunction[Any,Unit]
             root ! makeMessage(...)
                  ^
 6 errors found
(assignment/compile:compile) Compilation failed
[error] Total time: 108 s, completed Dec 19, 2013 9:07:46 PM

我该如何解决这个问题?

【问题讨论】:

  • 这是来自Principles of Reactive Programming course 的作业 5。应该这样标记。此外,硬期限将于 12 月 22 日到期。我不相信你同意在课程中发布类似答案的大代码sn-ps的荣誉代码。
  • 我只发布与我的问题相关的代码 sn-p。我不认为这违反了荣誉准则。按照建议,我将更新问题的标签。
  • 1.我不是指标签(被列入黑名单的 AFAIR),我的意思是在问题中包含相关信息。否则,您的行为可能会被其他人解释为不诚实行为。 2. 当然,张贴小片段通常没问题,但我认为这个问题和答案越界进入“不OK”领域。
  • @TheTerribleSwiftTomato:我不在这门课程中,我的答案只是一个明显的类型修复 + 小重构,没有任何秘密知识。
  • @senia :对不起,我说得不准确。我并不是说我认为你的行为是故意不道德的(我也不是 Dimitri 的)。我的意思是,在我看来,无论任何人的意图如何,在 SO 和 Coursera 接受的情况下,最终效果都是“不好”。当然,这主要是问题的错,你的回答确实是无害的。

标签: scala akka type-mismatch


【解决方案1】:

简答

替换这一行:

private def makeOperation(...): Receive = {

有了这个:

private def makeOperation(...): Unit = {

表达式operation match { ... } 的结果类型是Unit,因为它是每个早午餐中最后一个方法 (!) 的结果类型。

详情

方法makeOperation 命名错误。它真正做的是处理消息。

其实你根本不需要这个方法——你可以像这样处理normal中的消息:

val normal: Receive = {
  case Outer(MainOp(otherInt), someInt, true)
    if otherInt < someInt => root ! makeMessage(...)
  case Outer(MainOp(otherInt), someInt, true)
    if otherInt > someInt => ...
  case Outer(MainOp(otherInt), someInt, true) => ...
  case Outer(MainOp(otherInt), someInt, false)
    if otherInt < someInt => ...
  case Outer(MainOp(otherInt), someInt, false)
    if otherInt > someInt => ...
  case Outer(MainOp(otherInt), someInt, false) => ...
  case Outer(OtherOp1(...), someInt, someBool) => ...
  case Outer(OtherOp2(...), someInt, someBool) => ...
}

只有当你想像这样改变下一个消息(以及之后的所有消息)的actor行为时,你才需要一个结果类型为Receive的方法:

context become createNewBehavior(params)

有关示例,请参阅以下答案:

Initializing an actor before being able to handle some other messages

How to properly use akka actors in scala

Is it possible to do that in Scala (without mutating the internal state of a class)?

【讨论】:

    猜你喜欢
    • 2021-05-13
    • 2018-02-16
    • 1970-01-01
    • 2014-03-05
    • 2018-03-12
    • 2018-06-20
    • 2017-07-06
    • 2019-09-29
    • 1970-01-01
    相关资源
    最近更新 更多