我很难获得Scala3宏实现中的类型信息。我会用代码来解释问题。
下面是应用程序逻辑:
object BlockServiceImpl extends BlockService:
def authenticateUser0() = new ServiceCall[AuthUser,AuthUserResponse]:
def invoke(request: AuthUser): Future[AuthUserResponse] =
println("BlockServiceImpl authenticateUser0 called")
Future.successful(AuthUserResponse("test")) 现在,对于逻辑,我想用宏来创建端点。
defineRoute("POST","/v1/block",BlockServiceImpl.authenticateUser0)这是内联方法:
inline def defineRoute[Q: RootJsonFormat ,R: RootJsonFormat](method: String, uri: String,inline call: () => ServiceCall[Q,R]): AkkaHttpCall = ${ methodImpl[Q,R]('uri, 'call)}这就是宏的实现:
def methodImpl[Q: Type,R: Type](uri: Expr[String],expr: Expr[Function0[ServiceCall[Q,R]]])(using ctx: Quotes): Expr[AkkaHttpCall] = ...如何在编译时获得宏展开过程中Q是AuthUser类型的信息?
发布于 2021-05-11 10:34:14
如果Q和R是特例的话,我通过输入信息来解决这个问题(NotUsed,Done,..)在用于Q和R的序列化器中,这一思想取自于Lagom框架。
发布于 2021-05-07 10:03:36
一个可能的解决方案是对引用的表达式使用模式匹配。
因此,例如,可以定义用于检索编译时类型的方法:
def tag[A <: AnyKind] = throw new IllegalStateException("use it only to pattern match types")然后,在宏展开中,您可以执行模式匹配如下:
'{ tag[Q] } match {
case '{ tag[AuthUser] } => // here I am sure that Q is AuthUser, since Q is matched with AuthUser
}这是一个相当大的窍门(而且不是很容易扩展,因为你必须添加每一种类型),所以把我说的每句话都拿出来.我认为这是一个更清晰的解决方案,取决于您特定的应用程序逻辑:)
https://stackoverflow.com/questions/67422689
复制相似问题