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

创建类型参数取决于组合对象类型的Scala类的好方法,scala,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 ):

我正在磨练我的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]
  ...
}
val dfs = new DepthFirstSearch( new UnDirGraph[Integer](/*some params*/), 1 )
然后我有另一门课:

class DepthFirstSearch[ T ]( val graph: GraphLike[T], val sourceVertex: T )
{
  ...
}
目前,我发现必须这样做才能创建DepthFirstSearch类的实例

val dfs = new DepthFirstSearch[Integer]( new UnDirGraph[Integer](/*some params*/), 1 )
其中,
UnDirGraph
是一个
GraphLike
子类

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

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]
  ...
}
val dfs = new DepthFirstSearch( new UnDirGraph[Integer](/*some params*/), 1 )
目前,上述操作失败。。。有没有一种方法可以做到上述的事情

编辑:所以我得到的错误消息是 类型失配;找到:com.KGraph.GraphLike[Integer]
必需:com.KGraph.GraphLike[任何]
注:整数归功于@Régis Jean Gilles和@Mark Peters

Integer
1
(类型
Int
)的常见超类型是
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]
Scala会隐式地将
1
转换为
整数
,然后一切正常

正如@Régis Jean Gilles指出的那样,以下措施将起作用:

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

多了解一些信息就好了。例如,错误消息是什么?它推断类型/强制执行
T
的一致绑定,但不会自动查找和调用构造函数。您可以使用usng反射。你必须得到一个
类标签
(如果你要求,编译器会帮你做),然后陷入反射。由于您需要的不是默认(无参数)构造函数,因此它更适合于默认构造函数。我知道Java反射可以用于这类事情(我已经做到了),但我不熟悉这方面的2.10 Scala反射能力。这样可能就不那么难看了。@Kartik Aiyer:现在没有时间给出正确的答案,但是你应该知道
Integer
指的是
java.lang.Integer
,而不是原语
scala.Int
。将
Integer
更改为
Int
可能会解决您的问题(我在repl中快速尝试,发现
Integer
的方差错误,但
Int
的方差错误为零)@兰德尔·舒尔茨:我想你不知怎么地误解了这个问题。为了扩展,字面的
1
是一个
scala.Int
,而不是
java.lang.Integer
。因此,
T
的常见类型和唯一适用的推断是
Any
。但是如果
T
解析为
Any
,这意味着您将把
UnDirGraph[Int]
分配给一个
图形[Any]
,这是不允许的,因为
T
不是协变的(它是不变的)。因此,编译器建议使用
+T
而不是
T
。我真正感兴趣的是,一旦你添加了
[Integer]
,它就可以工作了,这表明
1
可以在强制时自动转换成
java.lang.Integer
,这是我还不知道的。@MarkPeters
1
转换成
java.lang.Integer
是常见的。在Scala中,
Predef.int2Integer
处理这个问题。