【问题标题】:Wrapper scala API over Java APIJava API 上的包装器 Scala API
【发布时间】:2016-09-25 03:30:50
【问题描述】:

我是 Scala 新手,我正在为我的 Java API 构建一个 Scala 包装器

我有四个 Java 接口

public interface Client<T> {
 <T> Handle<T> execute(App<T> app);
}

public interface App<T> extends Serializable{
  T process(AppContext context) throws Exception;
}

public interface AppContext {
  File getDirectory();
  void deleteDirectory();
  File createDirectory(String path);
}

public interface Handle<T> extends Future<T> {
   static interface Listener<T> {          
       void onSuccess(Handle<T> handle)
       void onFailure(Handle<T> handle, Throwable e)
   }

   void addListener(Listener<T> listener);
}

这是我的 Scala 等价物

trait Process[T] extends Future[T] { 
  // Few abstract methods
}


class ProcessImpl[T](handle: Handle[T]) extends Process[T] {

val promise = Promise[T]

override def isCompleted: Boolean = ???

override def onComplete[U](func: (Try[T]) => U)(implicit executor: ExecutionContext)  = {
  case Success(t) => promise.success(handle.get())
  case Failure(e) => promise.failure(e)
   }

override def value: Option[Try[T]] = ???

@throws(classOf[Exception])
override def result(atMost: Duration)(implicit permit: CanAwait): T = ???

@throws(classOf[InterruptedException])
@throws(classOf[TimeoutException])
override def ready(atMost: Duration)(implicit permit: CanAwait) = ???

 } 


class ScalaClient(javaClient: Client) {
   def execute[T](func: AppContext => T): ScalaHandle[T] = {
     val app = new App[T]
     @throws(classOf[Exception])
     override def process(AppContext context): T = func(context)

     val handle = javaClient.execute(app) // This returns a Handle obj. I want to convert it to ScalaHandle

    //My approach

     val scalahandle = new ProcessImpl(handle)       
     scalahandle
  }
}

我收到以下错误

匿名函数的参数类型必须是完全已知的。 (SLS 8.5)

预期类型为:单位 override def onComplete[U](func: (Try[T]) => U)(implicit executor: ExecutionContext) = {

另外,我想知道我的方法是否正确

【问题讨论】:

    标签: java scala interface future


    【解决方案1】:

    你的问题不在于onComplete本身——而在于你实现它的方式。

    override def onComplete[U](func: (Try[T]) => U)(implicit executor: ExecutionContext)  = {
      case Success(t) => promise.success(test.get())
      case Failure(e) => promise.failure(e)
    }
    

    在这里,您将onComplete 定义为来自某个函数Try[_] =&gt; U 的部分函数——类型未知,而且它绝对不会覆盖原始方法abstract def onComplete[U](f: (Try[T]) ⇒ U)(implicit executor: ExecutionContext): Unit。请注意,这里没有 case 匹配任何内容:这里的 func 不是 Try[T]

    作为旁注,我不得不提到你永远不应该扩展Future。一个非常有用的座右铭是,不惜一切代价避免继承。在你的情况下,我认为继承不会给你带来任何好处——相反,它会增加混乱。

    您可能正在寻找的是,

    def asFuture[T](handle: Handle[T]): Future[T] = {
      val promise = Promise[T]()
      handle.addListener(new Handle.Listener[T] {
        def onSuccess(handle: Handle[T]) {
          promise.trySuccess(handle.get())
        }
        def onFailure(handle: Handle[T], e: Throwable) {
          promise.tryFailure(e)
        }
      })
      promise.future
    }
    

    【讨论】:

    • 很抱歉没有提供明确的信息。我已经编辑了我的问题。我需要在这里继承才能为我的 API 提供一个非阻塞的 scala 未来。
    • 你不需要,你只是认为这是一种合理的方式。我建议您编写一个函数,该函数采用Handle, 在其上注册一个侦听器,当底层Handle 完成时,完成一个Promise。现在你返回这里的唯一东西是Promice.future——没有继承,没有耦合。
    • 但是将它放在 onComplete 中将是一个理想的 Scala API。虽然这可以通过添加侦听器来完成,但我觉得这不是 scala 的做法
    • 不会的; onComplete 已由 Future 提供,无需实现新的。
    • 在上面你发布的代码中应该是promise.trySuccess(handle.get) ??因为Handle&lt;T&gt; extends JFuture
    猜你喜欢
    • 1970-01-01
    • 2016-05-03
    • 2012-08-02
    • 1970-01-01
    • 1970-01-01
    • 2014-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多