如何保留并恢复izumi.reflect.Tag以处理Rule泛型实例?
解决方案1:在Rule中直接保存Tag[T]实例
修改Rule类,让每个实例直接持有对应的Tag[T]实例,避免类型信息丢失:
import izumi.reflect.Tag // 方式1:显式接收隐式Tag参数并保存 case class Rule[T](lhs: String, rhs: Repr[T])(implicit val tag: Tag[T]) // 方式2:保留上下文边界语法糖,同时保存Tag实例 case class Rule[T: Tag](lhs: String, rhs: Repr[T]) { val tag: Tag[T] = implicitly[Tag[T]] }
处理List[Rule[?]]时,提取每个Rule的Tag实例,显式传入process方法:
val rules: List[Rule[?]] = // 初始化规则列表 rules.foreach { r => r.tag match { case tag: Tag[t] => // 类型转换安全,因为Tag的类型与Rule的T严格匹配 process(r.asInstanceOf[Rule[t]])(tag) } } def process[T: Tag](rule: Rule[T]): Unit = { // 你的副作用处理逻辑,例如: println(s"处理类型为 ${Tag[T].tag.toString} 的规则:${rule.lhs}") }
解决方案2:从LightTypeTag恢复Tag[T](unsafe但可控)
如果已经保存了LightTypeTag,可以用izumi提供的Tag.unsafeFromLightTypeTag恢复Tag实例。该操作虽标记为unsafe,但在你的场景中,LightTypeTag来自原始Tag[T],类型一致性有保障:
修改Rule类:
import izumi.reflect.{Tag, LightTypeTag} case class Rule[T: Tag](lhs: String, rhs: Repr[T]) { val lightTag: LightTypeTag = Tag[T].tag }
处理列表时:
rules.foreach { r => val tag = Tag.unsafeFromLightTypeTag[r.T](r.lightTag) process(r.asInstanceOf[Rule[r.T]])(tag) }
解决方案3:重构process适配存在类型
直接让process接收存在类型的Rule[?],内部通过保存的Tag做类型分支处理:
def process(rule: Rule[?]): Unit = { rule.tag match { case tag: Tag[t] => tag.tag match { case t if t =:= Tag[String].tag => val strRule = rule.asInstanceOf[Rule[String]] println(s"处理String类型规则:${strRule.lhs} -> ${strRule.rhs}") case t if t =:= Tag[Int].tag => val intRule = rule.asInstanceOf[Rule[Int]] println(s"处理Int类型规则:${intRule.lhs} -> ${intRule.rhs}") case _ => println(s"处理未知类型规则:${rule.lhs}") } } } // 调用时直接传入即可 rules.foreach(process)
内容的提问来源于stack exchange,提问作者Todd O'Bryan
相关产品推荐
相关产品推荐

