gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 15:12:22 25 4
gpt4 key购买 nike

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

case class Response(thing: String)

class LibraryObject(stack: Seq[Processor])(implicit context: ExecutionContext) {
def entryPoint(data: String): Future[Response] = {
val response = Future(Response(""))
stack.foldLeft(response) { (resp, proc) => proc.process(data, resp) }
}
}

trait Processor {
def process(data: String, resp: Future[Response]): Future[Response]
}

它可能会被这样使用:

class ThingProcessor extends Processor {
override def process(data: String, response: Future[Response]) = {
response map { _.copy(thing = "THE THING") }
}
}

class PassThroughProcessor extends Processor {
override def process(request: Request, response: Future[Response]) = {
response
}
}

object TheApp extends App {
import ExecutionContext.Implicits.global

val stack = List(
new ThingProcessor,
new PassThroughProcessor
)
val libObj = new LibraryObject(stack)

val futureResponse = libObj.entryPoint("http://some/url")

// ...
}

我收到 ThingProcessor 的编译错误:

Cannot find an implicit ExecutionContext, either require one yourself or import ExecutionContext.Implicits.global



我的问题是,如何隐式提供 ExecutionContext那个 LibraryObject必须使用用户定义的对象( ThingProcessorPassThroughProcessor )或它们的方法,而不会让用户(将编写类的人)担心——也就是说,我希望用户没有输入:

class MyFirstProcessor(implicit context: ExecutionContext)

或者

override def process(...)(implicit context: 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
}

更新:
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()
}

关于scala - 将隐式 ExecutionContext 传递给包含的对象/调用的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17849749/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com