Scala 3如何通过quoted.Type获取泛型类型的字符串名称?
解决方案
问题根源
你遇到的编译错误是因为scala.quoted.Type是编译期宏上下文的专属类型,不能作为普通隐式参数传入宏方法,也不能跨非inline方法在运行时传递。下面给出两种可直接运行的实现方案:
方案1:使用Scala 3标准库Typeable(推荐)
Scala 3原生提供Typeable作为TypeTag的替代实现,支持完整泛型类型的运行时获取,用法和ClassTag完全一致,不需要自定义宏:
// 全局导包 import scala.reflect.Typeable object Example3: @main def example3() = print[String] // java.lang.String print[Int] // Int print[List[Double]] // scala.collection.immutable.List[Double] def print[A: Typeable]: Unit = println(getTypeString[A]) def getTypeString[A: Typeable]: String = Typeable[A].describe
这个方案不需要修改原有方法为inline,也不需要手写宏逻辑,所有泛型参数都会完整保留。
方案2:自定义宏+inline透传
如果你一定要基于quoted.Type自定义宏实现,只需要把所有用到泛型参数的调用链方法都标记为inline,确保编译期展开时能拿到真实类型:
object Macro1: import scala.quoted.* inline def getTypeString[A]: String = ${ getTypeStringImpl[A] } private def getTypeStringImpl[A: Type](using Quotes): Expr[String] = Expr(Type.show[A]) object Example3: @main def example3() = print[String] // java.lang.String print[Int] // Int print[List[Double]] // scala.collection.immutable.List[Double] inline def print[A]: Unit = println(Macro1.getTypeString[A])
该方案的原理是inline方法会在调用点直接展开,宏会捕获调用时传入的真实类型参数,不会出现泛型擦除的问题。
内容的提问来源于stack exchange,提问作者semptic
相关产品推荐
相关产品推荐

