原文链接 http://www.ituring.com.cn/article/131439
本文翻译自:Scala snippets 2: List symbol magic [email protected]
Scala的每一个操作符都可以是函数,所以重载操作符(实际上不是真正的重载操作符,毕竟操作符都已经是方法了)
是一件非常简单并且在很多库中都能看见的事。在这个片段中,我们将探讨一些让列表操作更加简单的方法重载。
让我们从++
操作符开始。首先,就像我们一直做的那样,让我们来创建一个列表:
scala> val list = 0 until 10 toList
list: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
scala> val list2 = 10 to 0 by -1 toList
list2: List[Int] = List(10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
然后大致浏览下来自 http://www.scala-lang.org/api/2.11.1/index.html#scala.collection.immutable.List 的一些操作:
第一个操作符是++
。我们可以用这个操作符把两个列表连接在一起,并且返回一个新的列表:
scala> val list3 = list ++ list2
list3: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
scala> val list3 = list2 ++ list
list3: List[Int] = List(10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
注意你并不需要保证列表是相同类型的。Scala会自动选择最相关的父类:
scala> val list1 = 0 to 10 toList
list1: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> val list2 = 10 to 0 by -1 toList
list2: List[Int] = List(10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
scala> val list3 = list1.asInstanceOf[List[Double]]
list3: List[Double] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> list3 ++ list2
res4: List[AnyVal] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
你可以看到最后的返回是AnyVal
类型的列表,这是对于Int
和Double
最常见的父类。
既然我们已经看过++
了,让我们来看看和++
看起来最相似的++:
。这个操作符和++
有着相同的语义,
不同的地方是结果的类型在++
中取决于左操作数而这个操作符取决于右操作数:
scala> vector1
res14: Vector[Int] = Vector(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
scala> list1
res15: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> vector1 ++ list1
res16: scala.collection.immutable.Vector[Int] = Vector(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> vector1 ++: list1
res17: List[Int] = List(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
接下来的两个操作符:+
和+:
可以让我们向后和向前对列表增加新的元素:
scala> 999 +: list1
res27: List[Int] = List(999, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> list1 :+ 999
res28: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 999)
还有什么?::
和:::
都是对列表之前增加一些东西的函数。::
操作符增加单个元素,而:::
操作符增加一个列表。
所以基本上他们是和+:
和++
操作一样的。主要的区别是+:
和++
可以被用于Traversable
,但::
和:::
只能用于列表。
scala> 11 +: list1
res38: List[Int] = List(11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> list1
res39: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> 11 +: list1
res40: List[Int] = List(11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> list2
res41: List[Int] = List(10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
scala> list1 ::: list2
res43: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
:\
和/:
用于折叠操作(看这里)。:\
从右至左折叠,而/:
从左至右:
scala> list1
res50: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> (1 /: list1)((r,i) => {println(i);i+r})
0
1
2
3
4
5
6
7
8
9
10
res51: Int = 56
scala> (list1 :\ 1)((i,r) => {println(i);i+r})
10
9
8
7
6
5
4
3
2
1
0
res52: Int = 56
你可以看到折叠的方向决定了元素是从前往后还是从后往前处理的。
这就是这个片段的全部。
本文仅用于学习和交流目的,不
时间: 2024-08-10 23:27:00