用于java API的Scala包装器API

时间:2016-05-20 06:23:45

标签: java scala closures scala-collections

我是Scala的新手,我需要为我的Java API提供scala包装器

我有三个Java接口

public interface Client<T> {

   <T> Future<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);

}

以下是创建App的Java代码

public class RandomApp extends App<String> {

  @Override
  public String process(AppContext context) {

      // Inorder to access the methods in AppContext I need to access  
      // it by the following way

      appContext.createDirectory("some path");
      return "random";
  }
 }

我希望客户端接口有一个Scala Wrapper,后者又调用Java API。但我对新的Scala API进行了一些修改

object ScalaConverter {

  implicit class ScalaWrapper(client: Client) {

  def scalaClient = new ScalaClient(client)

  }
}

class ScalaClient(client: Client) {

  def execute[T](appContext: AppContext => T): Future[T] = {

      // I am passing appContext as closure instead of passing in
      // App because I want to take the advantage of Closures in Scala

      // I basically want to create an App with this appContext and
      // pass it to the execute method

      // For example - but this is not working

      var app = // Need to create this app with appContext

      Future {
        client.execute(app)
      }
  }

}

1 个答案:

答案 0 :(得分:2)

如果我没弄错的话,你只是希望能够从一个以AppContext作为参数并返回任何对象的函数创建App对象(假设是T)。

因为尝试镜像整个java API并不是很有趣,所以只需按原样使用它,但添加一些扩展。要做到这一点,你应该使用implicits。

为此,我看到两种可能性:在Client接口上添加一个隐式类以向其添加一些函数,或者添加从(AppContext => T)App个对象的隐式转换

让我们使用第一个解决方案,你必须在一个对象中嵌入隐式类(如果你需要自动导入,这可以是一个包对象)。

object ScalaConverter {
  class ScalaApp[T](val block: AppContext => T) extends App[T] {
    def process(context: AppContext): T = block(context)
  }

  implicit class ScalaClient(client: Client) extends AnyVal{
    def execute[T](block: AppContext => T): Future[T] = {
      client.execute(new ScalaApp(block))
    }
  }
}

然后,您只需使用现有的Java客户端对象:

import ScalaConverter._
myJavaClient.execute { context => 
   ???
}

你应该得到原则,我可能犯了一个错误(没试过编译这个)