在Scala中哪一个更惯用/首选:Map(<stuff>:_ *)或<stuff> .toMap?</stuff> </stuff>

时间:2013-09-08 20:16:08

标签: scala scala-collections

这些似乎实际上是等同的:

scala> ("asd" zip "zxc").toMap
res62: scala.collection.immutable.Map[Char,Char] = Map(a -> z, s -> x, d -> c)

scala> Map(("asd" zip "zxc"): _*)
res63: scala.collection.immutable.Map[Char,Char] = Map(a -> z, s -> x, d -> c)

然而,现实生活中的差异是什么?哪一个比较惯用?运行时性能会有所不同吗?

我确信同样/类似的问题可能会被问到其他类似的结构对,所以请随意给出更一般/抽象的答案:)

2 个答案:

答案 0 :(得分:3)

两者之间存在真正的差异,因为 这些方法已定义:

  • apply 构造函数是在目标集合的伴侣中定义的:

    object Coll {
      def apply[T](els: T*): Coll[T] = ???
    }
    

    这意味着除了Seq元素之外,它绝对没有关于输入的信息,因此它只是遍历该序列并构建Coll

  • 另一方面,toSeqtoArray,...在 source 集合中定义,这意味着他们拥有关于其内部的所有额外信息

通常,您可以依靠toXXX方法在需要时进行短路,或者返回一些有意义的专门收藏。

作为一个愚蠢的例子,请考虑:

List(1,2,3).toSeq // toSeq returns `this`, there is no overhead
// vs.
Seq(List(1,2,3): _*) // this will copy that list into a new one...

如果用Stream.continually(1) ...

替换该列表,情况会变得更糟

答案 1 :(得分:0)

我个人更喜欢第一个变体,因为它更清晰可读。两者在性能或其他特征上没有实际差异。在第一种情况下,你创建一个索引seq,然后在第二种情况下将它转换为map,你使用这个seq提取器sintax :_*这是Scala最好的部分。就像Odersky教授告诉许多人一样,Scala设计的一部分是为不同的问题提供制作设计解决方案。所以在这种情况下,你可以选择任何。但正如我告诉你的第一个更清晰易懂,将核心符号编程留给Scalaz =)