3

我正在磨练我的 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 )

目前上述失败......有没有办法像上面那样做?

编辑:所以我得到的错误信息是类型不匹配;found : com.KGraph.GraphLike[Integer]
required: com.KGraph.GraphLike[Any] 注意:Integer <: Any,但 GraphLike trait 在类型 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]

4

1 回答 1

2

Credits to @Régis Jean-Gilles and @Mark Peters

Common super-type of Integer and 1 (of type Int) is Any. So when writing this:

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

The type inference gives you

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

But now, we need

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

which is not the case as UnDirGraph is invariant.

If you write:

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

Scala will implicitly convert the 1 to an Integer and then everything is fine.

As @Régis Jean-Gilles points out, the following will work:

val dfs = new DepthFirstSearch( new UnDirGraph[Int](/*some params*/), 1 )
于 2013-04-22T20:57:51.853 回答