创建类型参数取决于组合对象类型的Scala类的好方法
我正在磨练我的scala技能,我正在编写一些图形化算法。我有一个图形的API表示,类似这样创建类型参数取决于组合对象类型的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 ):
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
,这是我还不知道的。@MarkPeters1
转换成java.lang.Integer
是常见的。在Scala中,Predef.int2Integer
处理这个问题。