如果找不到元素,为什么Scala的索引方法返回-1而不是None?

时间:2012-12-31 01:29:32

标签: scala

我一直想知道为什么在Scala中用于确定集合中元素位置的各种索引方法(例如List.indexOfList.indexWhere)返回-1以指示缺席集合中给定元素的代替,而不是更惯用的Option[Int]。返回-1代替None是否有一些特别的优势,或者仅仅是出于历史原因?

3 个答案:

答案 0 :(得分:7)

这只是出于历史原因,但后来人们想知道历史原因是什么:历史是什么,为什么会这样呢?

直接历史记录是java.lang.String.indexOf方法,它返回索引,如果找不到匹配的字符,则返回-1。但这并不新鲜;如果在字符串中找不到字符,则Fortran SCAN函数返回0,这与Fortran使用1索引的情况相同。

这样做的原因是字符串只有正长度,因此任何负长度都可以用作None值,而不会有任何拳击开销。 -1是最方便的负数,所以就是这样。

如果编译器不够聪明,无法实现所有装箱和拆箱以及一切都无关紧要,这可能会增加。特别是,对象创建往往需要5-10 ns,而函数调用或比较通常需要1-2 ns,因此如果集合很短,创建一个新对象可能会有相当大的分数惩罚(如果你的记忆已被征税,GC还有很多工作要做。)

如果Scala最初有一个惊人的优化器,那么选择可能会有所不同,因为人们会用选项编写东西,这样更安全而不是特殊情况,然后相信编译器将其转换为适当的高性能代码。

答案 1 :(得分:1)

速度? (不确定)

def a(): Option[Int] = Some(Math.random().toInt)
def b(): Int = Math.random().toInt
val t0 = System.nanoTime; (0 to 1000000).foreach(_ => a()); println("" + (System.nanoTime - t0))
// 53988000
val t0 = System.nanoTime; (0 to 1000000).foreach(_ => b()); println("" + (System.nanoTime - t0))
// 49273000

你还应该经常检查索引< Some(index)

中的0

答案 2 :(得分:0)

只有返回Int才能使用Java的内置类型,而Option[Int]需要将整数包装在Object中。这意味着速度更快(如@idonnie所示),但也会增加内存使用量。

虽然Option非常适合作为一般工具(并且我经常使用它),但其他非价值演示文稿也是如此。 <{1}}或空字符串完全有效且有用。

使用Double.NaN的一个好处是能够将其作为集合传递给Option循环等。如果您不太可能这样做,则检查-1或for可能比执行NaN / None的匹配更简洁。