You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala 3反射中如何获取类体内成员的正确应用类型?

Scala 3反射中泛型类成员的实际类型获取问题

在处理泛型类Foo[T]的实例化类型Foo[Boolean]时,构造函数字段thing能正确显示为Boolean,但类体内定义的store: Option[T]却始终显示为泛型参数T——这是因为直接获取的是泛型类原始定义中的成员类型,没有将泛型参数替换为实例化时的实际类型。

解决思路

核心是构造类型参数替换映射,将泛型类定义中的类型参数(如T)替换为实例化时的实际类型(如Boolean),再用这个映射处理类成员的原始类型。

具体实现步骤

  1. 提取泛型类的类型参数与实际类型的映射
    从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的映射
    
  2. 实现类型替换函数
    递归遍历成员的原始类型,将其中的类型参数替换为实际类型:

    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 // 其他类型直接返回
    }
    
  3. 处理类成员类型
    获取类体内成员(如store)的原始类型后,用上述函数进行替换:

    // 假设已获取到store的原始类型storeRawType: Type
    val storeActualType = substituteType(storeRawType, substitutionMap)
    // 此时storeActualType就是Option[Boolean]
    

说明

构造函数字段thing之所以能直接显示为Boolean,是因为构造函数的参数类型在AppliedType的实例化过程中已经完成了类型参数替换,而类体内的成员类型是从泛型类的原始定义中读取的,因此需要手动执行替换逻辑。

内容的提问来源于stack exchange,提问作者Greg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 16:47:50