Scala列表拼接结果不符合预期的原因咨询
嘿,刚学Scala碰到这种操作符的坑太正常了!我来给你拆解清楚问题出在哪~
首先得明确两个列表操作符的本质区别:
::(常叫cons操作符):把单个元素加到列表头部,而且它是右结合的。注意哦,这里的“单个元素”可以是任何东西——如果你传进去一个列表,那这个列表就会被当作一个单独的元素塞进新列表里,而不是把它的元素拆出来合并。:::(拼接操作符):专门用来拼接两个完整的列表,把两个列表里的所有元素合并成一个新列表,同样是右结合。
再看你写的代码:
val allCars = "Toyota" :: "Innova" :: newCars ::: newCars :: newCars
因为Scala里以冒号结尾的操作符都是右结合,而且::和:::的优先级规则会让这个表达式的实际执行顺序和你想的不一样。咱们从右往左拆解一下:
- 先执行最右边的
newCars :: newCars:这里newCars是List("Ritz"),所以相当于把整个List("Ritz")作为单个元素加到另一个newCars的头部,得到List(List("Ritz"), "Ritz")。 - 接着执行
newCars ::: 上面的结果:也就是把List("Ritz")和List(List("Ritz"), "Ritz")拼接,得到List("Ritz", List("Ritz"), "Ritz")。 - 最后执行前面的
"Toyota" :: "Innova" :: 上面的结果:把两个字符串依次加到头部,最终得到List("Toyota", "Innova", "Ritz", List("Ritz"), "Ritz")——这就是你看到输出里有List(Ritz)的原因!
如果你想得到预期的输出(三个Ritz),得把所有列表拼接的地方都用:::,或者先把前面的单个元素转成列表再统一拼接。比如两种写法:
写法一:统一用:::拼接(把单个元素先做成列表)
val allCars = List("Toyota", "Innova") ::: newCars ::: newCars ::: newCars
写法二:保留::加单个元素,但用括号明确优先级,避免把列表当元素加进去
val allCars = "Toyota" :: "Innova" :: (newCars ::: newCars ::: newCars)
这两种写法执行后,allCars.foreach(println)都会输出你预期的结果:
Toyota Innova Ritz Ritz Ritz
内容的提问来源于stack exchange,提问作者DeathStar
相关产品推荐
相关产品推荐

