[英]How does one obtain the type of the value that an AST represents?
I'm trying to write the following: 我正在尝试编写以下内容:
import scala.reflect.runtime.universe._
val value: Tree = /* some AST */
val tpe = typeOf(value) // This should be the result type of the AST.
// This is pseudocode. What should
// actually go on this line?
q"""
type U = $tpe
val v: U = $value
"""
I need to capture the type of the value represented by the AST value
in tpe
and assign it to U
. 我需要捕获tpe
AST value
表示的value
的tpe
并将其分配给U
How does one do this? 如何做到这一点?
Edit: Giving a type annotation for value
and matching on it via quasiquotes isn't an option here. 编辑:这里没有给value
提供类型注释并通过准引用对其进行匹配的选项。 The use case is a Shapeless extensible record , which has complicated types such as String with labelled.KeyTag[1, String] :: Long with labelled.KeyTag[three, Long] :: HNil
for something like val ls = (1 ->> "two") :: ("three" ->> 4L) :: HNil
. 用例是一个Shapeless 可扩展记录 ,具有复杂的类型,例如String with labelled.KeyTag[1, String] :: Long with labelled.KeyTag[three, Long] :: HNil
,例如val ls = (1 ->> "two") :: ("three" ->> 4L) :: HNil
。 Also, the value
AST is programmatically generated and not a literal. 同样, value
AST是通过编程生成的,而不是文字。
Get a ToolBox
, use it to typecheck value
, and ask the annotated tree for its type. 获取一个ToolBox
,使用它来类型检查value
,并询问带注释的树的类型。
import scala.runtime.reflect.currentMirror
val toolbox = currentMirror.mkToolBox()
val tpe = TypeTree(toolbox.typecheck(value).tpe)
The code you've written states you're doing this at runtime. 您编写的代码说明您正在运行时执行此操作。 The use case you've stated in your comment makes it seem like you're in a compile-time macro. 您在注释中陈述的用例使您看起来好像在编译时宏中。 In that case, use the similar typecheck
method in your Context
. 在这种情况下,请在Context
使用类似的typecheck
方法。 It won't typecheck otherwise; 否则将不会进行类型检查; the value
would be a Tree
from the wrong Universe
, representing the fact that the new compiler instance made by ToolBox
operates in the context of the current program (which happens to be a compiler), while the reflection represented by the Context
is all about the future context of the code manipulated by the containing compiler. 该value
将是来自错误Universe
的Tree
,表示由ToolBox
的新编译器实例在当前程序(恰好是编译器)的上下文中运行的事实,而Context
表示的反射全部与以下内容有关:包含的编译器操纵的代码的将来上下文。
Try to use $tpt
in q"$mods val $tname: $tpt = $expr"
尝试在q"$mods val $tname: $tpt = $expr"
使用$tpt
val t: Tree = reify {
val value: Int = 3
}.tree
val tpe = t match {
case q"{$mods val $tname: $tpt = $expr; $_}" => tpt
} // Int
https://docs.scala-lang.org/overviews/quasiquotes/syntax-summary.html#definitions https://docs.scala-lang.org/overviews/quasiquotes/syntax-summary.html#definitions
Connected question: How does one use quasiquotes to obtain the type of a value? 关联问题: 如何使用准引数获取值的类型?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.