如何使用TypeTag创建通用生成器?

时间:2018-12-17 01:45:14

标签: scala generics reflection types type-erasure

给出以下类型层次结构:

sealed trait Edge[T]
sealed trait WeightedEdge[T] extends Edge[T]
sealed abstract class AbstractUndirectedEdge[T] extends Edge[T]
case class UndirectedEdge[T](...) extends AbstractUndirectedEdge[T]
case class UndirectedWeightedEdge[T](...) extends AbstractUndirectedEdge[T] with WeightedEdge[T]
case class DirectedEdge[T](...) extends Edge[T]
case class DirectedWeightedEdge[T](...) extends WeightedEdge[T]

sealed abstract class GraphBuilder[V, E <: Edge[V]]
sealed class UndirectedGraphBuilder[V, E <: AbstractUndirectedEdge[V]] extends GraphBuilder[V, E]
sealed class DirectedGraphBuilder[V, E <: DirectedEdge[V]] extends GraphBuilder[V, E]

我想创建一个构建器方法,该方法可以动态确定要返回的具体构建器实例。

def newBuilder[V, E <: Edge[V]](implicit tag: TypeTag[E]): GraphBuilder[V, E] = {
  tag.tpe match {
    case x if x <:< typeOf[DirectedEdge[V]] => new DirectedGraphBuilder[V, E]()
    case _ => new UndirectedGraphBuilder[V, E]()
  }
}

以上内容无法编译。

  

错误:(119,29)没有可用的TypeTag   DirectedEdge [V]案例x如果x <:新的DirectedGraphBuilder [V,E]()

     

错误:(119,29)没有足够的参数用于   方法typeOf:(隐式ttag:   reflect.runtime.universe.TypeTag [DirectedEdge [V]])reflect.runtime.universe.Type。   未指定的值参数ttag。         如果x <: new DirectedGraphBuilder [V,E]()

1 个答案:

答案 0 :(得分:1)

首先,您还需要为TypeTag提供V

def newBuilder[V, E <: Edge[V]](implicit tag: TypeTag[E], tag1: TypeTag[V]) = {
  tag.tpe match {
    case x if x <:< typeOf[DirectedEdge[V]] => new DirectedGraphBuilder[V, DirectedEdge[V]]()
    case _ => new UndirectedGraphBuilder[V, UndirectedEdge[V]]()
  }
}

然后修复,还要创建哪种类型的Edge。在创建时,某些时候应该以某种或其他方式固定类型。

然后就可以了,尽管用例尚不清楚。