2013-11-15 17 views
2

這是在indexWhere方法中的錯誤,或者是有前四行中的示例波紋管有意義的解釋?`list.indexWhere`當參數`from`的奇怪的結果是否定的

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 

回答

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其中開發者可以看看它。

3

我覺得最好你會看到一個IllegalArgumentException,如果你通過一個負數作爲起始指數(那是什麼意思呢?),但也許有人認爲,一個界限的開銷檢查WASN」值得。我沒有在文檔中看到任何指定的行爲,所以不知道我會把它稱爲一個錯誤;更多的是「垃圾進來,垃圾出來」的情況。

+2

那麼,錯誤就會有救了我的調試半小時,所以在我的情況下,它肯定是值得的。另外,所有這些線可以只返回2,因爲這仍然是正確的答案 - 如果我開始從一些假想負指數計數,數值大於3仍開始於指數2默默地返回錯誤的答案是最壞的替代品。雖然,我承認這絕對是一個「垃圾進入」的案例。 –

0

作爲一個未來的解決方案,你可能想實現自己的版本,確實檢查。你可能會使它返回一個選項,以及,而不是-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 
+0

這很整齊。不過我通常會避免包裝標準公用設施,除非我真的必須這樣做。如果出現這種情況過於頻繁,那麼這是有問題的編程語言或API吮吸一個明顯的跡象。我寧願抱怨,直到公用事業完成正確的方式™:-) –