我试图在一行中组合和初始化一个数组,大致相当于这样:
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]]
我以为它们是等价的?
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)
澄清一下为什么你的代码不起作用,以及它实际上在做什么。
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 个元素的通用顺序收集方法。
运行上面的代码尝试将 range 元素(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
期望函数本身。
语言的另一个意想不到的微妙之处,当我们仍然不完全熟悉它时,它会让我们感到惊讶。