如何在Scala 3宏中获得foo.asInstanceOf[SomeType]的等效值?

tyu7yeag  于 2023-10-18  发布在  Scala
关注(0)|答案(1)|浏览(115)

在我的macro impl中有这样一个例子:

def renderJsonFn(rt: RType): Expr[(Any,StringBuilder) => StringBuilder] = 

  val reflectedClassFieldInfo = ???
  val typeMaker = reflectedClassFieldInfo.fieldType.toType // (quotes: Quotes) => TypeRepr
  val fieldType = typeMaker(quotes).asType // Type[? <: AnyKind]

  '{(a:Any, sb:StringBuilder) => 

     val typedA = ?? // <<— need equivalent of a.asInstanceOf[fieldType] here

     val typedFieldValue = ${ 
       Select.unique('{ typedA }.asTerm, someFieldName).asExpr 
     }
     // This fails if I use ‘a’ —> someFieldName is not a member of Any
     // Having a:T is highly impractical—and just moves the problem.  Still need a way to typecast in a macro 
  }
bttbmeg0

bttbmeg01#

如果你有expr: Expr[A],AST会检查expr的值是否是Expr[B](因为它是这种类型,只是Scala出于某种原因不知道这一点,例如:你手工构造了这个expr,或者从某处收到了Term),你可以使用.asExprOf

expr.asExprOf[B] // requires given Type[B]

但是,如果您无法在编译时证明它(编译器应该在宏中抛出异常,毕竟您可以检查expr.asTerm.tpe <:< TypeRepr.of[B]),并且您希望在生成的代码中创建asInstanceOf[B]以在运行时执行强制转换,则可以使用引号和取消引号

'{ ${ expr }.asInstanceOf[B] } // also requires given Type[B]

相关问题