【问题标题】:Can't gain the `pipeTo` method on [[scala.concurrent.Future]]无法在 [[scala.concurrent.Future]] 上获得 `pipeTo` 方法
【发布时间】:2017-07-12 05:28:49
【问题描述】:

正如 akka 的文档所解释的,您应该能够通过这种方式在 [[scala.concurrent.Future]] 上获得 pipeTo 方法:

import akka.pattern.pipe
val future = ...
future pipeTo sender()

很遗憾,我做不到,我的 IDE 中出现错误“无法解析符号 pipeTo”。

作为一种解决方法,我不得不以这种方式使用语法

pipe(future) pipeTo sender()

但它仍然困扰我不知道为什么(我在 scala BTW 中很新)。非常感谢帮助理解这个谜题。

斯卡拉 2.12.2 akka 2.5.3

【问题讨论】:

  • 范围内是否有隐式执行上下文?

标签: scala akka


【解决方案1】:

您需要在范围内有一个implicit ExecutionContext,这是一个示例:

import akka.actor.{Actor, ActorSystem, Props}
import akka.pattern.pipe

import scala.concurrent.Future

// Get the implicit ExecutionContext from this import
import scala.concurrent.ExecutionContext.Implicits.global

object Hello extends App {

  // Creating a simple actor
  class MyActor extends Actor {
    override def receive: Receive = {
      case x => println(s"Received message: ${x.toString}")
    }
  }

  // Create actor system
  val system = ActorSystem("example")
  val ref = system.actorOf(Props[MyActor], "actor")

  // Create the future to pipe
  val future: Future[Int] = Future(100)

  // Test
  future pipeTo ref
}

控制台:

sbt run
[info] <stuff here>
[info] Running example.Hello 
Received message: 100

您必须这样做的原因是因为pipeToPipeableFuture 上的实例函数,而您的常规Future 必须“增强”为PipeableFuture。这是PipeableFuture的构造函数,注意implicit executionContext: ExecutionContext参数:

final class PipeableFuture[T](val future: Future[T])(implicit executionContext: ExecutionContext)

完整的类在这里,你可以看到pipeTo函数:

final class PipeableFuture[T](val future: Future[T])(implicit executionContext: ExecutionContext) {
  def pipeTo(recipient: ActorRef)(implicit sender: ActorRef = Actor.noSender): Future[T] = {
    future andThen {
      case Success(r) ⇒ recipient ! r
      case Failure(f) ⇒ recipient ! Status.Failure(f)
    }
  }
  def pipeToSelection(recipient: ActorSelection)(implicit sender: ActorRef = Actor.noSender): Future[T] = {
    future andThen {
      case Success(r) ⇒ recipient ! r
      case Failure(f) ⇒ recipient ! Status.Failure(f)
    }
  }
  def to(recipient: ActorRef): PipeableFuture[T] = to(recipient, Actor.noSender)
  def to(recipient: ActorRef, sender: ActorRef): PipeableFuture[T] = {
    pipeTo(recipient)(sender)
    this
  }
  def to(recipient: ActorSelection): PipeableFuture[T] = to(recipient, Actor.noSender)
  def to(recipient: ActorSelection, sender: ActorRef): PipeableFuture[T] = {
    pipeToSelection(recipient)(sender)
    this
  }
}

由于 pipe(future) 不是 Future 上的实例函数,因此它适用于您的示例。

【讨论】:

  • Intellij 给了我误导性错误Cannot resolve symbol pipeToimport scala.concurrent.ExecutionContext.Implicits.globalimport context.dispatcher
猜你喜欢
  • 2017-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-24
  • 2021-04-28
相关资源
最近更新 更多