我对scala很新,如果你能帮助我解决以下问题,我将不胜感激
我使用akka-http发送http请求我想声明一个通用的发送请求方法,它使用Unmarshall将http响应体转换为泛型类型。
我应该如何对T ???
发送请求实施:
def sendRequest[T](requestMessage :HttpRequestMessage) :Future[T] = { val promise = Promise[HttpResponse]() val request = requestMessage.request -> promise queue.offer(request).flatMap { case QueueOfferResult.Enqueued => promise.future.flatMap[AnyRef] { response => { response.entity.toStrict(FiniteDuration(3,"seconds")).flatMap { strict => Unmarshal(strict.getData).to[T] } } } } }
答案 0 :(得分:3)
如果你看一下Unmarshal object的代码,你可以看到to
中使用的类型参数有一定的约束 - 一个隐式的unmarshaller:
class Unmarshal[A](val value: A) {
/**
* Unmarshals the value to the given Type using the in-scope Unmarshaller.
*/
def to[B](implicit um: Unmarshaller[A, B], ec: ExecutionContext, mat: Materializer): Future[B] = um(value)
}
当将类型A的值解组为类型B的值时,范围中必须存在类型为Unmarshaller[A, B]
的隐式值。有许多预定义的unmarshallers(例如here是一些常用的,用于从String转换为各种类型,如Int,Boolean等),但您也可以定义自己的。这被称为类型类模式。
因此,如果您希望代码适用于某种类型T
,则必须确保该范围内有该类型的隐式解组器。这意味着您的方法sendRequest
必须具有Unmarshaller[Data, T]
类型的隐式参数,其中Data
应替换为strict,getData
的实际类型(我可以'从你的代码告诉)。
这样的事情:
def sendRequest[T](requestMessage: HttpRequestMessage)(implicit m: Unmarshaller[Data, T]): Future[T] // replace Data with concrete type
这允许编译to[T]
,但现在您有义务在调用to[T]
时在范围内实际具有此隐式值。如前所述,您有两个选项 - 导入预定义的unmarshallers(如前面所示的PredefinedFromStringUnmarshallers),或者定义您自己的选项。我不能告诉T
可以做什么,所以我不能比这更进一步地建议你,但重点是只要你为{{1}后面的具体类型提供unmarshaller (通过导入或手动定义),它应该工作;否则akka将不知道如何解散你的T。