我是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)
}
}
}
答案 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 =>
???
}
你应该得到原则,我可能犯了一个错误(没试过编译这个)