当参数`from`为负时,`list.indexWhere`的结果很奇怪

时间:2013-11-15 10:32:46

标签: scala scala-collections

这是indexWhere方法中的错误,还是对示例中的前四行有一个有意义的解释?

scala> List(1, 1, 4, 4, 4).indexWhere(_ > 3, -4)
res0: Int = -2

scala> List(1, 1, 4, 4, 4).indexWhere(_ > 3, -3)
res1: Int = -1

scala> List(1, 1, 4, 4, 4).indexWhere(_ > 3, -2)
res2: Int = 0

scala> List(1, 1, 4, 4, 4).indexWhere(_ > 3, -1)
res3: Int = 1

scala> List(1, 1, 4, 4, 4).indexWhere(_ > 3, 0)
res4: Int = 2

scala> List(1, 1, 4, 4, 4).indexWhere(_ > 3, 1)
res5: Int = 2

scala> List(1, 1, 4, 4, 4).indexWhere(_ > 3, 2)
res6: Int = 2

scala> List(1, 1, 4, 4, 4).indexWhere(_ > 3, 3)
res7: Int = 3

scala> List(1, 1, 4, 4, 4).indexWhere(_ > 3, 4)
res8: Int = 4

scala> List(1, 1, 4, 4, 4).indexWhere(_ > 3, 5)
res9: Int = -1

3 个答案:

答案 0 :(得分:3)

我认为理想情况下,如果您将负数作为起始索引(无论如何应该是什么意思?),您会看到IllegalArgumentException,但也许有人认为边界检查的开销是'值得的。我在文档中没有看到任何指定的行为,所以不确定我会把它称为bug;更多的是“垃圾,垃圾”。

答案 1 :(得分:1)

源代码如下所示:

override /*SeqLike*/
  def indexWhere(p: A => Boolean, from: Int): Int = {
    var i = from
    var these = this drop from
    while (these.nonEmpty) {
      if (p(these.head))
        return i

      i += 1
      these = these.tail
    }
    -1
  }

因此没有输入检查,也没有i变量的归零。我会说这是一个错误。如果可以的话,请在https://groups.google.com/forum/#!forum/scala-language上写一下开发人员可以查看的内容。

答案 2 :(得分:0)

作为未来的解决方案,您可能希望实现 检查的自己的版本。你可以让它返回一个Option而不是-1,这也是不安全的:

implicit class WithIndexWhereSafe[T](seq: Seq[T]) { 
  def indexWhereSafe(p: T => Boolean, from: Int) = { 
    assert(from >= 0, "from must be >= 0")
    val i = seq.indexWhere(p, from) 
    if (i != -1)
      Some(i)
    else
      None
  }
}


List(1, 1, 4, 4, 4).indexWhereSafe(_ > 3, 2)  // Some(2)
List(1, 1, 4, 4, 4).indexWhereSafe(_ > 3, 5)  // None
List(1, 1, 4, 4, 4).indexWhereSafe(_ > 3, -4) // AssertionError