请原谅我对Scala的不理解。我只是一个想要在Play框架中工作的Java开发人员。我甚至试图使用Java代码来实现一个特性,但是我得到了更加晦涩的错误。我有以下Scala代码:故障扩展Scala的未来[T]特性
package models
import scala.concurrent.Future
class SettableFuture[T](name: String) extends Future[T] {
var assignedValue: T
def set(newValue: T) =
assignedValue = newValue
//override abstract methods in Future[T]
def ready(atMost: scala.concurrent.duration.Duration)(implicit permit: scala.concurrent.CanAwait): models.SettableFuture[T] =
this
def result(atMost: scala.concurrent.duration.Duration)(implicit permit: scala.concurrent.CanAwait): T =
assignedValue
def isCompleted: Boolean =
false
def onComplete[U](func: scala.util.Try[T] => U)(implicit executor: scala.concurrent.ExecutionContext): Unit =
null
def value: Option[scala.util.Try[T]] =
null
}
这是我的错误:
overriding method ready in trait Awaitable of type (atMost: scala.concurrent.duration.Duration)(implicit permit: scala.concurrent.CanAwait)SettableFuture.this.type; method ready has incompatible type
忽略的,现在的方法的返回值,他们是荒谬的,因为我只是试图解决所有编译错误。
我简单地从扩展特性时编译时异常中复制了方法存根,而不覆盖其抽象方法并将它们粘贴到我的源文件中。我不明白为什么我仍然有错误。我在Awaitable看了ready()的签名,看起来返回类型实际上应该是类。
编辑:为什么我要实现这个原因是因为在Promise/Future Scala API中,我只能找到让我异步执行长时间运行的阻塞任务的东西。我所追求的是一些可以暂停请求的执行,直到感兴趣的东西在SettableFuture实例中设置一个值,从而完成发送响应的Promise。这样就有点像延续了。总之,这里是我结束了工作代码:
package models
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicInteger
import scala.concurrent.CanAwait
import scala.concurrent.ExecutionContext
import scala.concurrent.Future
import scala.concurrent.duration.Duration
import scala.util.Try
class SettableFuture[T]() extends Future[T] {
private final val ValueNotSet = 0
private final val ValueBeingSet = 1
private final val ValueSet = 2
private val valueStatus: AtomicInteger = new AtomicInteger(ValueNotSet)
private val onCompleteWaitHandle: CountDownLatch = new CountDownLatch(1)
private var onComplete: Try[T] => _ = _
private var assignedValue: T = _
/** Set a value and complete this Future.
*
* Returns false if the value has already been set by a past call to this method.
* Otherwise, marks this Future as complete, executes the function passed to
* onComplete, and finally returns true.
*/
def set(newValue: T): Boolean = {
//set value and trigger onComplete only once
if (valueStatus.compareAndSet(ValueNotSet, ValueBeingSet)) {
assignedValue = newValue
valueStatus.set(ValueSet)
onCompleteWaitHandle.countDown()
if (onComplete != null)
onComplete(Try(assignedValue))
true
}
false
}
//override abstract methods in the Future[T] trait
def ready(atMost: Duration)(implicit permit: CanAwait): this.type = {
onCompleteWaitHandle.await(atMost.length, atMost.unit)
this
}
def result(atMost: Duration)(implicit permit: CanAwait): T = {
ready(atMost)
assignedValue
}
def isCompleted: Boolean = (valueStatus.get() == ValueSet)
def onComplete[U](func: Try[T] => U)(implicit executor: ExecutionContext): Unit =
onComplete = func
def value: Option[Try[T]] = {
if (!isCompleted)
None
Some(Try(assignedValue))
}
}
感谢您的帮助。我现在已经完全使用了Scala代码。至于Promise和Future,我不确定这是否正是我想要实现的。我觉得大部分API都处理长时间运行,阻塞任务。我所追求的是一些可以暂停请求的执行,直到感兴趣的东西在SettableFuture实例中设置一个值,从而完成发送响应的Promise。这样就有点像延续了。您是否知道Scala库中存在的任何类似的东西? –
@KevinJin这就是'Promise'的意思。将设置该值的代码保留对Promise'p'的引用,它将在未来的某个时刻用值完成。等待该值的计算获得对'p.future'的引用,并且可以以通常的方式(注册回调,映射等)对将来的完成作出反应。 –