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

如何在Scala 3中重写获取宿主对象内单例对象的反射方法?

在Scala 3中实现按声明顺序收集单例对象的反射方法

实现代码

import scala.reflect.ClassTag
import scala.reflect.runtime.universe.*

def allSingletonObjects[A: ClassTag](host: Any): Vector[A] = {
  val mirror = runtimeMirror(host.getClass.getClassLoader)
  val classSymbol = mirror.classSymbol(host.getClass)
  
  classSymbol.info.declared
    .filter(_.isModule)
    .map { sym =>
      mirror.reflectModule(sym.asModule).instance.asInstanceOf[A]
    }
    .toVector
    .reverse
}

关键调整说明

  1. 替换members为declared:Scala 3反射中members会包含所有继承来的成员,而declared仅返回当前对象自身声明的成员,精准匹配需求——只收集host对象内部定义的单例。
  2. 添加ClassTag[A]上下文绑定:这是Scala 3中更规范的写法,能避免类型转换时的编译器警告,同时保证类型参数A的运行时信息可用。
  3. 保留reverse操作:Scala反射的成员遍历顺序与代码声明顺序相反,和Scala 2的行为一致,反转后才能得到符合预期的声明顺序结果。

验证示例

使用题目中的Color定义测试:

sealed trait Color

object Color {
  case object Red extends Color
  case object Green extends Color
  case object Blue extends Color
}

// 调用结果
allSingletonObjects[Color](Color) // 输出: Vector(Color.Red, Color.Green, Color.Blue)

注意事项

  • 确保传入的host是Scala对象(而非Java类),因为模块符号是Scala特有的反射概念。
  • 题目明确所有目标单例均继承自A,因此asInstanceOf[A]的类型转换是安全的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 20:42:03