IndexedSeq [Int]与Array [Int]

杰·普拉布(Jai Prabhu)

来自Java背景,我正在学习Scala,以下内容使我感到非常困惑。为什么在这两个(非常相似但不同)的构造中返回的类型不同,它们仅在构建源集合的方式上有所不同-

  val seq1: IndexedSeq[Int] = for (i <- 1 to 10) yield i

  val seq2: Array[Int] = for (i <- Array(1, 2, 3)) yield i

请为我指出正确的文献,以便在这里我能理解核心基础。

约格午间

通常,有两种不同样式的收集操作库:

  • 保留类型:这就是您在问题中感到困惑的地方
  • 通用的(不是“参数多态性”的意思,而是单词的标准英语意义)或“同质的”

类型保持收集操作尽量准确地保存类型操作,例如filtertakedrop等,仅利用现有未经修改的元素。对于类似的操作map,它将尝试查找仍可以保存结果的最接近的超类型。例如,将IntSet具有从Int函数的映射String显然不会导致IntSet,而只会导致Set将映射IntSetBoolean可以在中表示BitSet,但我知道没有一个足够聪明的集合框架可以真正做到这一点。

通用/同类收集操作始终返回相同的类型。通常,选择此类型非常通用,以适应最广泛的用例。例如,在.NET中,集合操作返回IEnumerable;在Java中,它们返回Streams;在C ++中,它们返回迭代器;在Ruby中,它们返回数组。

直到最近,才有可能通过复制所有类型的所有操作来实现类型保留的收集操作。例如,Smalltalk集合框架是保留类型的,它通过让每个单个集合类重新实现每个单个集合操作来做到这一点。这导致大量重复的代码,并且是维护的噩梦。(巧合的是,发明了许多新的面向对象的抽象方法,并就其如何应用于Smalltalk集合框架撰写了第一篇论文。有关示例,请参见特性:行为的可组合单位。)

据我所知,Scala 2.8集合框架的重新设计另请参见SO上的此答案)是有人第一次设法创建保留类型的集合操作,同时又将复制减少到最小程度(尽管没有消除)。但是,Scala 2.8集合框架被广泛批评为过于复杂,并且在过去十年中需要不断地工作。实际上,它实际上也导致了Scala文档系统的完全重新设计,只是为了能够隐藏类型保留操作所需的非常复杂的类型签名但是,这还不够,因此collection框架被完全丢弃并重新设计了再次在Scala 2.13中(此重新设计花了几年时间。)

因此,对您的问题的简单答案是:Scala尝试尽可能保留集合的类型。

在第二个情况下,集合的类型Array,当你map过了Array,你回来了Array

在第一种情况下,集合的类型为Range现在,aRange实际上没有元素。它只有一个起点,一个终点和一个步骤,并且在您迭代时按需生成元素。因此,Range用新元素生产新产品并不容易map功能基本上需要能够对映射功能进行“逆向工程”,以弄清楚新的起点和终点以及步骤应该是什么。(这相当于解决停止问题,换句话说,这是不可能的。)如果执行以下操作,该怎么办:

val seq1: IndexedSeq[Int] = for (i <- 1 to 10) yield scala.util.Random.nextInt(i)

在这里,甚至没有明确定义的步骤,因此实际上不可能构建一个Range执行此操作的步骤。

因此,很明显,映射到aRange不能返回a Range因此,它做的第二件事是:它返回可以包含映射值最精确的超类型Range在这种情况下,恰好是IndexedSeq

在保留类型的集合操作方面,我们遇到了麻烦,我们认为这是某些操作合同的一部分。例如,大多数人会争辩说,集合的基数应该在下不变map,换句话说,map应该将每个元素映射到一个新的元素,因此map永远不要更改集合的大小。但是,这段代码呢:

Set(1, 2, 3).map { _ % 2 == 0 }
//=> Set(true, false)

在这里,您从中获得了元素较少的集合,该集合map仅应转换元素,而不能删除它们。但是,由于我们决定要保留类型的集合,并且aSet不能有重复的值,所以两个false值实际上是相同的值,因此集合中只有一个。

[可以争论的是,这实际上仅表明Sets不是集合,不应将其视为集合。Sets是谓词(“此元素是成员吗?”)而不是集合(“给我所有元素!”)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在Scala中轻松将IndexedSeq [Array [Int]]转换为Seq [Seq [Int]]?

来自分类Dev

Scala:从Array [Array [Int]]到Array [Int]

来自分类Dev

Scala类型推断:无法从Array [T]推断IndexedSeq [T]

来自分类Dev

Scala从Array [T]隐式转换为IndexedSeq [T]

来自分类Dev

从Array [T]到IndexedSeq [T]的Scala隐式转换

来自分类Dev

flatten a list of int array

来自分类Dev

从MutableList <Int>初始化Array <Int>

来自分类Dev

MiniZinc:类型错误:预期的int的array [int],实际的var opt int的array [int]

来自分类Dev

将 Array{Int, 1} 转换为 Array{Int, 2}

来自分类Dev

How to cast JSONArray to int array?

来自分类Dev

将int变量放入Array

来自分类Dev

'Array<Element>' 不能转换为 'Array<Int>'

来自分类Dev

int * array [60]和int * array之间的区别= new int(60);

来自分类Dev

int * array [60]和int * array之间的区别= new int(60);

来自分类Dev

从Array.BinarySearch <T>(T [],int,int,T)引发的ArgumentException

来自分类Dev

Java中Scala的Array [Int] v / s int []的内存比较?

来自分类Dev

seq <int>和array <int>之间的Dafny区别

来自分类Dev

从Array.BinarySearch <T>(T [],int,int,T)引发的ArgumentException

来自分类Dev

array <int,5> b之间的区别;和int b [5];

来自分类Dev

'初始化':无法从'Array <int,3>'转换为'int'

来自分类Dev

IndexedSeq并删除多个元素

来自分类Dev

检查int或list <int>

来自分类Dev

'(Int,Int)'与'CGPoint'不同

来自分类Dev

用int []添加int

来自分类Dev

[[Int]] -> [Int] 与乘法

来自分类Dev

用 int* 返回 int

来自分类Dev

将Array [Int]转换为Map [Int,Int]的Scala功能样式

来自分类Dev

Java Int Array返回全0

来自分类Dev

Int Array []不能很好地打印。

Related 相关文章

热门标签

归档