【问题标题】:Why is Scala's Range a data structure instead of a function? [closed]为什么 Scala 的 Range 是数据结构而不是函数? [关闭]
【发布时间】:2016-05-17 23:11:32
【问题描述】:

我来自 Python 和 R 等语言的背景,这两种语言都有 range() 函数返回该语言的公共集合类型(Python 的 range() 返回一个列表,而 R 的 range() 返回一个向量)。

所以我很惊讶 Scala 提供Range,不是作为函数,而是作为数据类型。更令人惊讶的是,Range 不仅仅是ListVector 等更常见的集合类型的别名,而是它自己的独立数据类型!

谁能解释一下 Scala 设计理念的哪一部分导致 Range 成为一种独特的数据类型?

【问题讨论】:

  • 请注意,Python 的 range 仅在 Python 2 中生成列表。在 Python 3 中,它是一种非常类似于 Scala 的数据类型。
  • 为什么这让您感到惊讶?在实践中,两者有区别吗? Guava 带有用于 Java 的 Range 类型。一般来说,您应该期望不同的语言做出不同的设计决策。

标签: scala


【解决方案1】:

RangeList 之间的差异

RangeList 是两个不同的概念,因此它们在Scala 中实现为两个不同的类。 List 是一系列值的特定实现。这些可以是任何顺序的任何值。另一方面RangeInts的有序序列的实现,可以用三个Ints来描述:startendstep(起始值、结束值和一个步骤)大小)。

List(1, 4, 7, 10, 13) 表示与Range(1, 14, 3) 相同的东西,但不同。 Range 超过 List 用作范围的主要优点是 Range 内存效率更高。用作范围的List 在内存中保存该范围内的所有整数,其中Range 仅在内存中保存startendstep 的值。

范围在常数空间中表示,因为它们可以被定义 只有三个数字:它们的开始、结束和步进值。 由于这种表示,大多数对范围的操作都是 非常快。 [source]

您可以通过在其上调用toListRange 转换为List(或toVector/toArray 将其转换为相应的集合类型)。

通过调用方法创建Range

在 Scala 中,创建Ranges 的首选方法是调用tountilby 方法(在scala.runtime.RichIntRange 类中定义):

val r1: Range = 1 to 10       // range from 1 to 10 including 1 and 10  with step size 1
val r2: Range = 1 until 10    // range from 1 to 10 including 1 but not 10  with step size 1
val r3: Range = 1 to 10 by 3  // range from 1 to 10 including 1 and 10 with step size 3

【讨论】:

    【解决方案2】:

    为什么没有返回列表的函数

    与 Python 3 的 range(和 Python 2 的 xrange)一样,Scala 的 Range 是一个可迭代的结构,它只按需生成范围内的元素,实际上并不将它们存储在内存中。这比大范围的列表更可取,因为将它们存储在内存中会消耗大量内存,通常没有任何好处,因为大多数范围的使用不需要将元素存储在内存中。这也是为什么 Python 引入了xrange,后来又用它替换了旧的range

    那么为什么不使用返回Seq 之类的函数

    您可以询问Range 它的起始值、结束值和步长是多少。如果它只是一个Seq,你就不能这样做。

    【讨论】:

      猜你喜欢
      • 2011-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多