为什么prepend在Seq上的行为有所不同,具体取决于你如何调用它?

时间:2015-11-06 18:37:14

标签: scala

如果我使用中缀表示法,我可以附加到不可变的Seq没问题:

scala> Seq("b", "c") :+ "d"
res2: Seq[String] = List(b, c, d)

但如果我尝试使用前置,则会将String实例视为Seq本身,结果不同:

scala> Seq("b", "c") +: "a"
res3: scala.collection.immutable.IndexedSeq[Any] = Vector(List(b, c), a)

但是,以经典的方式调用该方法可以实现"期望":

scala> Seq("b", "c").+:("a")
res4: Seq[String] = List(a, b, c)

为什么它会以这种方式运行?应该有什么方法可以将String元素添加到Seq[String](惯用的scala)?

  

环境:Welcome to Scala version 2.11.6 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_79).

2 个答案:

答案 0 :(得分:3)

在中缀表示法中使用时,以冒号(:)结尾的每个方法都是右关联的。

所以你需要做"a" +: Seq("b", "c")

Seq("b", "c") +: "a"之所以有效,是因为StringIndexedSeq[Char],而您正在SeqList作为默认实施,通过Seq.apply)前置这是String,因此您获得了IndexedSeq[Any]

答案 1 :(得分:1)

您错过了关于如何将运算符表示法转换为方法调用的内容。

大部分时间a op b变为a.op(b)

但是,如果运营商的名称以冒号'结尾,那么a op b实际上是b.op(a)

因此,要致电seq.+:("a"),您必须撰写"a" +: seq。这更好,因为" a"来到结果的前面。这就是为什么名称被选为+:(并且附加名称为+:,仅用于对称)。

另一方面,当你写seq +:" a"时,它意味着" a"。+ :( seq)应该加上seq作为单个值,(不是++),字符串"a",即Seq[Char]。由于该单个值不是Char,因此结果不能是字符串,而是使用混合类型退化为List[Any]