【发布时间】:2013-04-23 04:57:51
【问题描述】:
我正在磨练我的 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 )
其中UnDirGraph 是GraphLike 子类
我必须在new DepthFirstSearch[Integer] 中指定类型参数。有没有一种方法可以让类型检查器从提供的图形参数中推断出来。我发现我做不到
做这样的事情
val dfs = new DepthFirstSearch( new UnDirGraph[Integer](/*some params*/), 1 )
目前上述方法失败...有没有办法可以完成上述操作?
编辑:所以我得到的错误信息是
类型不匹配;发现:com.KGraph.GraphLike[Integer]
必需:com.KGraph.GraphLike[任何]
注意:Integer <: any graphlike trait t>
这就是我尝试创建的方式
val graph = Graphing.createUndiGraphFromFile(
new File("/Volumes/Data/Users/kartik/ScalaSpace/Graph/tinyG.txt" ) )
val dfs = new DepthFirstSearch( graph, 0 )
crateUndiGraphFromFile 返回一个 GraphLike[Integer]
【问题讨论】:
-
多一点信息会很好。例如错误信息是什么?
-
它推断类型/强制
T的一致绑定,但它不会自动查找和调用构造函数。你可以使用反射来做到这一点。你必须得到一个ClassTag(如果你问,编译器会为你做这件事)然后陷入反射。而且由于您需要默认(无参数)构造函数以外的其他东西,因此对于默认构造函数来说,它会更加新颖。我知道 Java 反射可以用于这类事情(我已经做过),但我不熟悉该领域的 2.10 Scala 反射功能。那样有可能不那么丑。 -
@Kartik Aiyer:现在没有时间给出正确的答案,但你应该知道
Integer指的是java.lang.Integer,而不是原始的scala.Int。将Integer更改为Int可能会解决您的问题(我在repl 中快速尝试过,Integer出现差异错误,但Int没有出现差异错误)。 @Randall Schulz:我认为你误解了这个问题,不知何故。 -
展开,文字
1是scala.Int,而不是java.lang.Integer。因此,common 类型,并且仅适用于T的推断是Any。但是如果T解析为Any,这意味着您将分配一个UnDirGraph[Int]给一个不允许的GraphLike[Any],因为T不是协变的(它是invariant )。因此编译器建议使用+T而不是T。对我来说真正有趣的部分是,一旦你添加了[Integer],它就可以工作,这表明1可以在强制时自动转换为java.lang.Integer,这是我还不知道的。 -
@MarkPeters
1被转换为java.lang.Integer是常见的拳击。在 Scala 中,Predef.int2Integer负责处理这个问题。
标签: scala