创建Scala类的好方法,其Type参数取决于组合对象Type

时间:2013-04-22 16:05:13

标签: scala

我正在磨练我的scala技能,我正在编写一些图形算法。我有一个图表的API表示,就像这样

trait GraphLike[T]
{
  val vertices: Map[ T, VertexLike[T] ] 
  def addVertex( t: T ): GraphLike[T]
  def addEdge( a:T, b:T ): GraphLike[T]
  def getAdjacencyList( a: T ): List[T]
  def getVertex( a: T ): VertexLike[T]
  ...
}

然后我又开了一个班:

class DepthFirstSearch[ T ]( val graph: GraphLike[T], val sourceVertex: T )
{
  ...
}

目前我发现我必须这样做才能创建DepthFirstSearch类的实例

val dfs = new DepthFirstSearch[Integer]( new UnDirGraph[Integer](/*some params*/), 1 )

其中UnDirGraphGraphLike子类

我必须在new DepthFirstSearch[Integer]中指定类型参数。有没有一种方法,类型检查器可以从提供的图形参数推断出这一点。我发现我不能 做这样的事

val dfs = new DepthFirstSearch( new UnDirGraph[Integer](/*some params*/), 1 )

目前上述情况失败了......有没有办法像上面这样做?

编辑:所以我得到的错误信息是     类型不匹配;发现:com.KGraph.GraphLike [整数]
    要求:com.KGraph.GraphLike [任意]     注意:整数&lt ;: Any,但特性GraphLike是不变的     在类型T中。您可能希望将T定义为+ T。 (SLS 4.5)

这就是我尝试创建的方式

val graph = Graphing.createUndiGraphFromFile( 
            new File("/Volumes/Data/Users/kartik/ScalaSpace/Graph/tinyG.txt" ) )
val dfs = new DepthFirstSearch( graph, 0 )

其中crateUndiGraphFromFile返回GraphLike [Integer]

1 个答案:

答案 0 :(得分:2)

致@RégisJean-Gilles和@Mark Peters的信用

Integer1Int类型)的常见超类型为Any。所以写这篇文章的时候:

val dfs = new DepthFirstSearch( new UnDirGraph[Integer](/*some params*/), 1 )

类型推断为您提供

val dfs = new DepthFirstSearch[Any]( new UnDirGraph[Integer](/*some params*/), 1 )

但现在,我们需要

new UnDirGraph[Integer](/*some params*/) <: UniDirGraph[Any]

情况并非如此,因为UnDirGraph是不变的。

如果你写:

val dfs = new DepthFirstSearch[Integer]( new UnDirGraph[Integer](/*some params*/), 1 )

Scala会隐式地将1转换为Integer然后一切都很好。

正如@RégisJean-Gilles指出的那样,以下内容将起作用:

val dfs = new DepthFirstSearch( new UnDirGraph[Int](/*some params*/), 1 )