scala将列表转换为akka。贾皮。函数[akka.http.javadsl.model.HttpRequest,java.util.concurrent.CompletionStage[akka.http.javadsl.model.HttpResponse]]*
我试图动态添加传递到函数concatOrNotFound
中的服务
import akka.grpc.javadsl.ServiceHandler;
import akka.http.javadsl.model.HttpRequest;
import akka.http.javadsl.model.HttpResponse;
import akka.japi.function.Function;
Function<HttpRequest, CompletionStage<HttpResponse>> greeterService =
GreeterServiceHandlerFactory.create(new GreeterServiceImpl(mat), sys);
Function<HttpRequest, CompletionStage<HttpResponse>> echoService =
EchoServiceHandlerFactory.create(new EchoServiceImpl(), sys);
@SuppressWarnings("unchecked")
Function<HttpRequest, CompletionStage<HttpResponse>> serviceHandlers =
ServiceHandler.concatOrNotFound(greeterService, echoService);
Http.get(sys)
.newServerAt("127.0.0.1", 8090)
.bind(serviceHandlers)
(https://doc.akka.io/docs/akka-grpc/current/server/walkthrough.html)
concatOrNotFound
具有以下方法签名:
@scala.annotation.varargs
def concatOrNotFound(handlers : akka.japi.Function[akka.http.javadsl.model.HttpRequest, java.util.concurrent.CompletionStage[akka.http.javadsl.model.HttpResponse]]*) : akka.japi.Function[akka.http.javadsl.model.HttpRequest, java.util.concurrent.CompletionStage[akka.http.javadsl.model.HttpResponse]] = { /* compiled code */ }
如何通过greeterService
&echoService
进入as列表,然后在这个List
上调用ServiceHandler.concatOrNotFound
由于handlers
是一个varargs,我尝试了以下方法:
List serviceList = new ArrayList();
serviceList.add(eventService);
serviceList.add(echoService);
@SuppressWarnings("unchecked") // Calling varargs method with generic instances
final Function<HttpRequest, CompletionStage<HttpResponse>> serviceHandlers =
ServiceHandler.concatOrNotFound(l.toArray(new Function[serviceList.size()]));
但这会因编译器错误而失败:
Cannot resolve method 'concatOrNotFound(java.lang.Object[])'
我试图实现的是使用一个服务列表,该列表被转换为varargs,并被传递到concatOrNotFound方法中。我想使用列表的原因是,列表将根据条件逻辑填充,条件逻辑将决定哪些服务被添加到列表中
我正在考虑的另一个选项是迭代列表,并为每个列表元素调用concatOrNotFound,其中每个列表元素都是服务
更新:
这似乎可以使用varargs参数将List
传递给方法:
List<akka.japi.Function<akka.http.javadsl.model.HttpRequest, java.util.concurrent.CompletionStage<akka.http.javadsl.model.HttpResponse>>> serviceList = new ArrayList();
serviceList.add(eventService);
serviceList.add(echoService);
final Function<HttpRequest, CompletionStage<HttpResponse>> serviceHandlers =
ServiceHandler.concatOrNotFound(Iterables.toArray(serviceList, akka.japi.Function.class));
将列表类型参数显式输入到
List<akka.japi.Function<akka.http.javadsl.model.HttpRequest, java.util.concurrent.CompletionStage<akka.http.javadsl.model.HttpResponse>>>
由于类型擦除而需要吗
# 1 楼答案
我假设在这种情况下,源于scala的编译字节码可能与实际的预期编写源代码不同。这是scala编程的陷阱之一,尤其是在Varag scala/Java互操作性方面
或者
greeterService
和echoService
被推断为没有公共层次结构的不同类型,可能是由于vararg转换本身。这就是在你第一次尝试时,它们被推断为Object
类型的原因。看看ServiceHandler的源代码:应该是JFunction对于第二次尝试,您正在执行
List serviceList = new ArrayList();
这同样会将元素推断为Object
实例,因此编译器会失败是的,这是必需的,但与类型擦除无关。泛型类型作为编译过程的一部分被丢弃。提供具体的元素类型只允许编译器理解正确的类型被传递给期望它们的函数调用
我面前没有源代码,但您可以首先键入convert将服务转换为
JFunction
实例。你的运气可能会更好。另一种方法是首先使用正确键入的JFunction
数组来收集它们