为什么此Scala Akka代码无法编译?

问题描述 投票:0回答:1

我遇到了我不理解的编译错误:

[error] /Users/nicu/mooc-reactive/akkahttp-typed-actors-cluster-ORMap-followers/src/main/scala/followers/HttpServer.scala:43:76: type mismatch;
[error]  found   : akka.actor.typed.ActorRef[Res] => Req
[error]     (which expands to)  akka.actor.typed.ActorRef[scala.collection.immutable.Map[followers.UserId,followers.User]] => followers.FollowCommand
[error]  required: akka.actor.typed.ActorRef[Res] => Map[followers.UserId,followers.User]
[error]     (which expands to)  akka.actor.typed.ActorRef[scala.collection.immutable.Map[followers.UserId,followers.User]] => Map[followers.UserId,followers.User]
[error]             val usersStateFuture: Future[Res] = followersActorRef.ask[Res](func)

在我看来,这个签名:

def ask[Res](replyTo: ActorRef[Res] => Req)(implicit timeout: Timeout, scheduler: Scheduler): Future[Res]  

仅应表示将创建一个类型为ActorRef [Res]的临时参与者,并且replyTo函数可用于以一种包含对临时参与者的回复引用的方式创建到目标参与者的消息。然后在收到完整的承诺后,Res将完成返回的未来。在我的情况下,消息(Req)是一个Command,更确切地说是FollowCommand,而答案(Res)是一个Map [UserId,User],具有目标参与者管理的当前状态。

我不能简单地理解为什么它不能编译,谢谢。

package followers

import akka.Done
import akka.actor.typed.scaladsl.Behaviors
import akka.actor.typed.scaladsl.adapter._
import akka.actor.typed.{ActorRef, ActorSystem, Behavior, Scheduler}
import akka.http.scaladsl.Http
import akka.http.scaladsl.server.Route
import akka.http.scaladsl.server.directives.PathDirectives._
import akka.util.Timeout

import scala.concurrent.Future

object HttpServer {
  val guardianBehavior: Behavior[Done] = Behaviors.setup[Done](context => {
    val followersGraphActorRef = context.spawn(FollowersData.defaultBehavior(Map()), "followersGraph")
    context.watch(followersGraphActorRef)
    Http()(context.system.toClassic).bindAndHandle(route(followersGraphActorRef), "localhost", 8080)
    Behaviors.receiveMessage {
      case Done => Behaviors.stopped
    }
  })
  val system: ActorSystem[Done] = ActorSystem[Done](guardianBehavior, "demo-system")

  def route(followersActorRef: ActorRef[Map[UserId, User]]): Route =
    pathPrefix("root") {
      import akka.http.scaladsl.server.Directives._
      import akka.http.scaladsl.server.directives.MethodDirectives.get
      import akka.http.scaladsl.server.directives.PathDirectives.path
      import akka.http.scaladsl.server.directives.RouteDirectives.complete
      concat(
        pathEnd {
          get {
            import akka.actor.typed.scaladsl.AskPattern._
            import scala.concurrent.duration._
            implicit val timeout: Timeout = Timeout(5.seconds) // usually we'd obtain the timeout from the system's configuration
            implicit val scheduler: Scheduler = system.scheduler
            type Res = Map[UserId, User]
            type Req = FollowCommand
            val func: ActorRef[Res] => Req = (replyTo: ActorRef[Map[UserId, User]]) =>  FollowCommand(UserId(1), UserId(2), replyTo)

//            def ask[Res](replyTo: ActorRef[Res] => Req)(implicit timeout: Timeout, scheduler: Scheduler): Future[Res] = {
            val usersStateFuture: Future[Res] = followersActorRef.ask[Res](func)
            onSuccess(usersStateFuture)(usersState =>
              complete(usersState.toString)) //todo json
          }
        }
        //        path(Segment) {
        //          case "segment1" =>
        //        }
      )
    }


}
scala akka akka-stream akka-http
1个回答
1
投票

原因是我打电话问的演员类型。固定后,该actor当然是ActorRef [Req]类型。参与者具有请求的类型(他们可以接收的消息类型)。以前它在ActorRef [Response]上面的代码中。

© www.soinside.com 2019 - 2024. All rights reserved.