1

我试图在一行中组合和初始化一个数组,大致相当于:

var characterMap = new Array[List[ActorRef]](sizeX*sizeY)
characterMap.indices.foreach(characterMap(_) = Nil)

这似乎不起作用:

var characterMap = ((0 until sizeX*sizeY) map Nil).toArray[List[ActorRef]] 

但这确实:

var characterMap = (for (_ <- 0 until sizeX*sizeY) yield Nil).toArray[List[ActorRef]]

我以为他们是等价的?

4

2 回答 2

4
var characterMap = (for (_ <- 0 until sizeX*sizeY) yield Nil).toArray[List[ActorRef]]

被翻译成:

var characterMap = (0 until sizeX*sizeY).map(_ => Nil).toArray[List[ActorRef]]

这应该有效。

挑剔:它们不等同,它们是相同的。for只是糖语法。

顺便说一句,您可能需要考虑:

Array.fill[List[ActorRef]](sizeX*sizeY)(Nil)
于 2013-06-07T00:36:26.830 回答
0

澄清一下为什么您的代码不起作用,以及它实际上在做什么。

val characterMap = ((0 until 10) map Nil)

我已经简化了一点以使其更易于理解。

(0 until 10)是一个Range对象,其map方法(对于其他集合等)需要一个类型的函数(A) => B
A = Int在我们的例子中

既然类型检查器对 很满意map Nil,它看起来Nil一定是一个函数(Int) => B,可能吗?

这里的重点是Nil(i: Int)可以用作Nil.apply(i: Int)实际存在的语法糖!

这是获取第i 个元素的通用顺序收集方法。

运行上述代码尝试将范围元素转换为对象(0,1,...,9)对应的索引值Nil,即为空List

当然空列表中没有元素,所以抛出错误,如图

scala> val characterMap = ((0 until 10) map Nil)
java.lang.IndexOutOfBoundsException: 0
    at scala.collection.LinearSeqOptimized$class.apply(LinearSeqOptimized.scala:52)
    at scala.collection.immutable.List.apply(List.scala:84)
    at scala.collection.immutable.List.apply(List.scala:84)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
    at scala.collection.immutable.Range.foreach(Range.scala:141)
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
    at scala.collection.AbstractTraversable.map(Traversable.scala:105)
    ...

结论

yield并且map具有相同的语义含义,但语法规则略有不同。

虽然yield期望映射函数的结果,但map期望函数本身。

该语言的另一个意想不到的微妙之处可能会让我们感到惊讶,而我们仍然不完全熟悉它。

于 2013-06-08T14:35:22.420 回答