for循环和范围的奇怪行为:found:Int required:scala.collection.generic.CanBuildFrom [Nothing,String,?]

时间:2015-07-05 18:53:36

标签: scala compiler-errors

我说奇怪,因为以下代码编译了很长时间没有投诉也没有评论。

val depth = dbStuff.lookupSomeInt(blah, blah)
for (x: Int <- 0 to depth) {
 doStuffWith(x).orNot
}

然而今天它没有在我的一台机器上编译(同时仍然在另一台机器上编译)

这是错误:

[error] /Users/SomeOne/SomePath/SomeFile.scala:415: type mismatch;
[error]  found   : Int
[error]  required: scala.collection.generic.CanBuildFrom[Nothing,String,?]
[error]           for (x: Int <- 0 to depth) {
[error]                               ^
[error] one error found

在食物链的上游,我添加了一个val:

  protected implicit val columnOrderByList = Seq.empty[Seq[String]]

这是我所知道的唯一变化,并且在添加后立即发生错误。

修复似乎是:

   for (x: Int <- Range(0, depth, 1)) {
     doStuffWith(x).orNot
   }

它拒绝所有其他尝试让“范围”起作用:例如括号等(0 to depth)

讨厌说出来但是错误就像吓唬了我一样。如果这是500个编译错误而不是1,会发生什么?或者,如果“修复”没有变得不言自明怎么办?更糟糕的是,如果根本原因不明显也是如此,那么甚至不可能退出?

我确信有些天才确切地知道这里发生了什么以及为什么但是我不知道如何找出(如在后面的路径中)来解决我的寂寞......

欢迎光!

COMFIRMED:我删除protected implicit val columnOrderByList并且原始代码编译没有问题 - 我把它放回去并且我得到了记录的错误。在食物链上,我的意思是val在一个类中,该类由具有此编译错误的类继承,因此val将在范围内。

1 个答案:

答案 0 :(得分:1)

这只是许多隐式转换在范围内时可能发生的问题之一。

scala> 0 to 3
res0: scala.collection.immutable.Range.Inclusive = Range(0, 1, 2, 3)

相当于

scala> intWrapper(0) to 3
res1: scala.collection.immutable.Range.Inclusive = Range(0, 1, 2, 3)

然而,

scala> implicit val s: Seq[Seq[String]] = null
s: Seq[Seq[String]] = null

scala> 0 to 3
<console>:12: error: type mismatch;
 found   : Int(3)
 required: scala.collection.generic.CanBuildFrom[Nothing,String,?]
       0 to 3
            ^

相当于

scala> s(0) to 3
<console>:12: error: type mismatch;
 found   : Int(3)
 required: scala.collection.generic.CanBuildFrom[Nothing,String,?]
       s(0) to 3
               ^

scala> s.apply(0) to 3
<console>:12: error: type mismatch;
 found   : Int(3)
 required: scala.collection.generic.CanBuildFrom[Nothing,String,?]
       s.apply(0) to 3
                     ^

您新引入的隐式值具有比预定义值更高的优先级,因此选择它。通常,这不应该是一个问题,但在这种情况下Seq定义了一个方法to,它可以将一个集合转换为一个不同类型的集合。其完整signaturedef to[Col[_]](implicit cbf: CanBuildFrom[Nothing, A, Col[A]]): Col[A],其中解释了有关预期CanBuildFrom的错误消息。

Lection:尽可能减少隐含的范围。