【发布时间】:2019-04-24 11:15:41
【问题描述】:
在第三方库中有一系列的请求类,它们都派生自一些通用的基类,是泛型的,以响应类为参数:
abstract class AbstractRequest[ResponseType] {
…
def execute(): ResponseType
}
class UserList {…}
class UserListRequest extends AbstractRequest[UserList] {…}
class Avatar {…}
class AvatarRequest extends AbstractRequest[Avatar] {…}
…
我想编写一些通用方法,它接受一个请求实例,以一些特殊的方式执行它多次,并将响应的处理委托给参数中提供的函数:
def specialMultiExecute(request: Req)(responseHandler: Resp => Unit): Unit = …
——被称为:
val myRequest: UserListRequest = …
specialMultiExecute(myRequest){ userList => … }
问题是我需要在specialMultiExecute 声明中以某种方式指定Req 和Resp 类型。我尝试了明显的方法:
def specialMultiExecute[Req <: AbstractRequest[Resp], Resp](request: Req)(responseHandler: Resp => Unit): Unit = …
——但 Scala 编译器无法推断出通用参数类型(需要像 specialMultiExecute[UserListRequest, UserList](myRequest){ userList => … } 这样的显式规范)。
在这种情况下,在 C++ 中,我可以使用单个模板参数Req 编写模板函数,同时将Resp 确定为方法Req::execute 的结果类型: p>
template<typename Req>
void specialMultiExecute(
Req request,
std::function<void (decltype(std::declval<Req>().execute()))> responseHandler
) {…}
//i.e. we use `decltype(std::declval<Req>().execute())` instead of Resp
有没有办法写出类似Scala的东西?
我的意思是(在类似 Scala 的伪代码中):
def specialMultiExecute[Req <: abstractrequest req>ResultTypeOf(Req#execute) => Unit): Unit = …
【问题讨论】:
-
您需要知道您拥有
AbstractRequest的哪个子类型,还是只知道您拥有哪个ResponseType就可以了吗? -
@LuisMiguelMejíaSuárez,说实话,
specialMultiExecute似乎最好知道AbstractRequest的确切子类型。 (从上面的解释来看,这可能并不明显,但它与specialMultiExecute内部如何工作的一些未指定的脏细节有关。)但是,如果我理解正确,您的第一个示例涵盖了这种情况(我现在正在尝试阅读并了解其工作原理)。