Scala 中两个标签中最不常见的 TypeTag?
Least common TypeTag from two tags in Scala?
Scala 的 TypeTag 相对容易比较和捕获 - 但 Scala 是否提供任何作用于 2 个标签的组合函数?例如,我正在以一种非常通用的方式使用标签(也就是说,类型 T 消失了)。我可以要求 Scala 为我提供最不常见父项的 TypeTag 吗?这看起来合乎逻辑,因为编译器和各种编辑器 IDE 可以轻松完成此操作并显示公共父级。示例:
Class A
Class B extends A
class C extends A
val tagB:TypeTag[_] = implicitly[TypeTag[B]]
val tagC:TypeTag[_] = implicitly[TypeTag[C]]
val res:TypeTag[_] = lcmFunction(tagB,tagC) //not a real function name .. example only
res // yields a TypeTag such that res.tpe =:= TypeTag[A].tpe
Universe
上有一个 lub
方法,它将计算类型列表的最小上限。
class A
class B extends A
class C extends A
class D extends C
class E extends C
class F extends E
import scala.reflect.runtime.universe._
val a = typeTag[A]
val b = typeTag[B]
val c = typeTag[C]
val d = typeTag[D]
val e = typeTag[E]
val f = typeTag[F]
scala> lub(List(b.tpe, c.tpe))
res17: reflect.runtime.universe.Type = A
scala> lub(List(b.tpe, c.tpe)) =:= a.tpe
res18: Boolean = true
scala> lub(List(e.tpe, f.tpe))
res19: reflect.runtime.universe.Type = E
scala> lub(List(c.tpe, d.tpe, f.tpe))
res21: reflect.runtime.universe.Type = C
从结果 Type
中创建一个 TypeTag
似乎有点棘手,但如 this answer 中所示是可能的。
Scala 的 TypeTag 相对容易比较和捕获 - 但 Scala 是否提供任何作用于 2 个标签的组合函数?例如,我正在以一种非常通用的方式使用标签(也就是说,类型 T 消失了)。我可以要求 Scala 为我提供最不常见父项的 TypeTag 吗?这看起来合乎逻辑,因为编译器和各种编辑器 IDE 可以轻松完成此操作并显示公共父级。示例:
Class A
Class B extends A
class C extends A
val tagB:TypeTag[_] = implicitly[TypeTag[B]]
val tagC:TypeTag[_] = implicitly[TypeTag[C]]
val res:TypeTag[_] = lcmFunction(tagB,tagC) //not a real function name .. example only
res // yields a TypeTag such that res.tpe =:= TypeTag[A].tpe
Universe
上有一个 lub
方法,它将计算类型列表的最小上限。
class A
class B extends A
class C extends A
class D extends C
class E extends C
class F extends E
import scala.reflect.runtime.universe._
val a = typeTag[A]
val b = typeTag[B]
val c = typeTag[C]
val d = typeTag[D]
val e = typeTag[E]
val f = typeTag[F]
scala> lub(List(b.tpe, c.tpe))
res17: reflect.runtime.universe.Type = A
scala> lub(List(b.tpe, c.tpe)) =:= a.tpe
res18: Boolean = true
scala> lub(List(e.tpe, f.tpe))
res19: reflect.runtime.universe.Type = E
scala> lub(List(c.tpe, d.tpe, f.tpe))
res21: reflect.runtime.universe.Type = C
从结果 Type
中创建一个 TypeTag
似乎有点棘手,但如 this answer 中所示是可能的。