Scala 将隐式ExecutionContext传递给包含的对象/被调用的方法

Scala 将隐式ExecutionContext传递给包含的对象/被调用的方法,scala,scala-2.10,executioncontext,Scala,Scala 2.10,Executioncontext,我正在使用Scala 2.10创建一个异步库。库的构造函数获取一系列实现特定特征的用户定义对象,然后库类上的方法将一些数据逐个发送到用户定义对象中。我希望用户在设置主实例时为异步操作提供ExecutionContext,然后根据需要将该上下文传递到用户定义的对象中。简化(伪?)代码: case类响应(thing:String) 类LibraryObject(堆栈:Seq[Processor])(隐式上下文:ExecutionContext){ def入口点(数据:字符串):未来[响应]={ va

我正在使用Scala 2.10创建一个异步库。库的构造函数获取一系列实现特定特征的用户定义对象,然后库类上的方法将一些数据逐个发送到用户定义对象中。我希望用户在设置主实例时为异步操作提供
ExecutionContext
,然后根据需要将该上下文传递到用户定义的对象中。简化(伪?)代码:

case类响应(thing:String)
类LibraryObject(堆栈:Seq[Processor])(隐式上下文:ExecutionContext){
def入口点(数据:字符串):未来[响应]={
val响应=未来(响应(“”)
stack.foldLeft(response){(resp,proc)=>proc.process(data,resp)}
}
}
特征处理器{
def进程(数据:字符串,resp:Future[Response]):Future[Response]
}
可以这样使用:

类ThingProcessor扩展了处理器{
覆盖def进程(数据:字符串,响应:未来[response])={
响应映射{{{.copy(thing=“THE thing”)}
}
}
类PassThroughProcessor扩展处理器{
覆盖def过程(请求:请求,响应:未来[响应])={
响应
}
}
对象应用程序扩展应用程序{
导入ExecutionContext.Implicits.global
val stack=列表(
新的东西处理器,
新的直通处理器
)
val libObj=新库对象(堆栈)
val futureResponse=libObj.entryPoint(“http://some/url")
// ...
}
我得到
ThingProcessor
的编译错误:

找不到隐式ExecutionContext,您自己需要一个或导入
ExecutionContext.Implicits.global

我的问题是,如何向用户定义的对象(
ThingProcessor
PassThroughProcessor
)或它们的方法隐式提供
ExecutionContext
,而不让用户(编写类的人)担心——也就是说,我希望用户不必键入:

类MyFirstProcessor(隐式上下文:ExecutionContext) 或

重写def进程(…)(隐式上下文:ExecutionContext)={…}

隐式作用域包括伴随对象和基类的类型参数

或者,library.submit(new library.Processor{def process()…})

这是可行的,但不是我的第一个想法,更聪明的是:

import concurrent._
import concurrent.duration._

class Library(implicit xc: ExecutionContext = ExecutionContext.global) {
  trait Processor {
    implicit val myxc: ExecutionContext = xc
    def process(i: Future[Int]): Future[Int]
  }

  def submit(p: Processor) = p process future(7)
}

object Test extends App {
  val library = new Library
  val p = new library.Processor {
    def process(i: Future[Int]) = for (x <- i) yield 2 * x
  }
  val res = library submit p
  val z = Await result (res, 10.seconds)
  Console println z
}
并发导入_
导入concurrent.duration_
类库(隐式xc:ExecutionContext=ExecutionContext.global){
特征处理器{
隐式val myxc:ExecutionContext=xc
def进程(i:Future[Int]):Future[Int]
}
def提交(p:处理器)=p进程未来(7)
}
对象测试扩展应用程序{
val库=新库
val p=新库处理器{

def过程(i:Future[Int])=用于(x这显然不适用于单例对象……你能想出一个解决办法吗?@Pagota_5b你的意思是喜欢更新吗?如果我思维不清晰,请提前道歉。是的,看起来很流畅,我也很喜欢。@Pagota_5b在不需要静态链接到库的情况下进行了更新。如果库本质上是一个数据源,也许你想选择提交到哪里.对于静态链接,我认为处理器[A]
import concurrent._
import concurrent.duration._
import java.util.concurrent.Executors

class Library()(implicit xc: ExecutionContext = ExecutionContext.global) {
  trait Processor {
    implicit val myxc: ExecutionContext = xc
    def process(i: Future[Int]): Future[Int]
  }

  def submit(p: Processor) = p process future(7)
}

object ctx {
  val xc = ExecutionContext fromExecutorService Executors.newSingleThreadExecutor
}
object library1 extends Library
object library2 extends Library()(ctx.xc)
object p extends library1.Processor {
  def process(i: Future[Int]) = for (x <- i) yield 2 * x
}
object q extends library2.Processor {
  def process(i: Future[Int]) = for (x <- i) yield 3 * x
}

object Test extends App {
  val res = library1 submit p
  //val oops = library2 submit p
  //val oops = library1 submit q
  val z = Await result (res, 10.seconds)
  Console println z
  Console println (Await result (library2 submit q, 10.seconds))
  ctx.xc.shutdownNow()
}
class Library(implicit xc: ExecutionContext = ExecutionContext.global) {

  def submit(p: Processor): Future[Int] = p dueProcess future(7)
}
trait Processor {
  implicit var myxc: ExecutionContext = _
  def dueProcess(i: Future[Int])(implicit xc: ExecutionContext) = {
    myxc = xc
    process(i)
  }
  protected def process(i: Future[Int]): Future[Int]
}

object ctx {
  val xc = ExecutionContext fromExecutorService Executors.newSingleThreadExecutor
}
object Test extends App {
  def db() = Console println (new Throwable().getStackTrace mkString ("TRACE [\n  ", "\n  ", "\n]"))
  val library = new Library()(ctx.xc)
  val p = new Processor {
    protected def process(i: Future[Int]) = for (x <- i) yield { db(); 2 * x }
  }
  val res = library submit p
  val z = Await result (res, 10.seconds)
  Console println z
  ctx.xc.shutdownNow()
}