Scala 3反射中如何获取类体内成员的正确应用类型?
Scala 3反射中泛型类成员的实际类型获取问题
在处理泛型类Foo[T]的实例化类型Foo[Boolean]时,构造函数字段thing能正确显示为Boolean,但类体内定义的store: Option[T]却始终显示为泛型参数T——这是因为直接获取的是泛型类原始定义中的成员类型,没有将泛型参数替换为实例化时的实际类型。
解决思路
核心是构造类型参数替换映射,将泛型类定义中的类型参数(如T)替换为实例化时的实际类型(如Boolean),再用这个映射处理类成员的原始类型。
具体实现步骤
提取泛型类的类型参数与实际类型的映射
从AppliedType(即Foo[Boolean]的反射类型)中,获取泛型类的类型参数符号,以及对应的实际类型参数:val appliedType: AppliedType = // 你的Foo[Boolean]反射类型 val classSymbol = appliedType.tycon.typeSymbol.asClass val typeParams = classSymbol.typeParams // 获取泛型类的类型参数(这里是T) val actualArgs = appliedType.args // 获取实例化时的实际类型(这里是Boolean) val substitutionMap = typeParams.zip(actualArgs).toMap // 构建T → Boolean的映射实现类型替换函数
递归遍历成员的原始类型,将其中的类型参数替换为实际类型:import scala.quoted.* import scala.reflect.Typeable def substituteType(tpe: Type, substitution: Map[Symbol, Type]): Type = tpe match { case TypeRef(pre, sym, args) => TypeRef(substituteType(pre, substitution), sym, args.map(substituteType(_, substitution))) case tp: TypeParamRef => substitution.getOrElse(tp.symbol, tp) case other => other // 其他类型直接返回 }处理类成员类型
获取类体内成员(如store)的原始类型后,用上述函数进行替换:// 假设已获取到store的原始类型storeRawType: Type val storeActualType = substituteType(storeRawType, substitutionMap) // 此时storeActualType就是Option[Boolean]
说明
构造函数字段thing之所以能直接显示为Boolean,是因为构造函数的参数类型在AppliedType的实例化过程中已经完成了类型参数替换,而类体内的成员类型是从泛型类的原始定义中读取的,因此需要手动执行替换逻辑。
内容的提问来源于stack exchange,提问作者Greg
相关产品推荐
相关产品推荐

