【转】Scala 片段2:List的操作符魔法

原文链接 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类型的列表,这是对于IntDouble最常见的父类。

既然我们已经看过++了,让我们来看看和++看起来最相似的++:。这个操作符和++有着相同的语义,

不同的地方是结果的类型在++中取决于左操作数而这个操作符取决于右操作数:

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

【转】Scala 片段2:List的操作符魔法的相关文章

【转】Scala 片段3:列表的map,flatMap,zip和reduce

原文链接 http://www.ituring.com.cn/article/131442 本文翻译自:Scala snippets 3: Lists together with Map, flatmap, zip and reduce [email protected] 如果不了解map,flatMap,zip和reduce函数,你就不能真正地谈论scala. 通过这些函数,我们可以非常容易地处理列表的内容并结合Option对象工作. 你可以在这个站点找到更多的片段: Scala片段 1:Fo

【转】Scala片段 1:Folding

原文链接  http://www.ituring.com.cn/article/131425 本文翻译自: Scala snippets 1: Folding 个人能力有限 如翻译不恰当的地方麻烦指正下^_^ [email protected] Scala为Java开发者提供了很多不错的特性和类库以此来编写更优美和简洁的代码. 但一下子要理解这么多的概念是一件困难的事.在这个由短小的文章组成的系列中, 我将会示范一些scala背后的观点,并且向你展示如何使用它们. 这个系列没有严格的结构,我只是

(转)scala学习笔记(8): 列表的map,flatMap,zip和reduce

http://www.ituring.com.cn/article/131442 https://twitter.github.io/scala_school/zh_cn/collections.html#flatten 如果不了解map,flatMap,zip和reduce函数,你就不能真正地谈论scala.通过这些函数,我们可以非常容易地处理列表的内容并结合Option对象工作.你可以在这个站点找到更多的片段:Scala片段 1:FoldingScala 片段2:List的操作符魔法 让我们

【转】Scala学习——操作符

原文链接 http://nerd-is.in/2013-08/scala-learning-operators/ 原文发表于:http://nerd-is.in/2013-08/scala-learning-operators/ 本章介绍如何实现自定以操作符.操作符和隐式转换通常用来构建领域特定语言(DSL). 本章还会介绍apply.update和unapply等特殊方法. 标志符 原来标志符是支持Unicode的…虽然我真的见过用中文名作为变量名的代码, 但是我一向以来学到的都是:标志符,可

Scala基础语法(声明定义、标识符命名、Scala脚本入门)

一.声明与定义(赋值) 1.val, 常量声明   val x:T val x:T=e 2.var, 变量声明   var x:T var x:T=e ?类型省略(默认类型)val x=e var x=e ? 声明省略(连续声明) val x1,x2,x3 等价于 val x1;val x2; var x1,x2,x3:T=e  等价于  var xn:T=e 3.def,函数声明def abc(xn:T):T*=e def adder(m:Int,n:Int) =m+n def adder()

Scala学习笔记及与Java不同之处总结-从Java开发者角度

Scala与Java具有很多相似之处,但又有很多不同.这里主要从一个Java开发者的角度,总结在使用Scala的过程中所面临的一些思维转变. 这里仅仅是总结了部分两种语言在开发过程中的不同,以后会陆续更新一些切换后在开发过程中值得注意的地方.以下列举了部分,但令人印象深刻的Scala语言的不同之处,具体的代码演示样例及具体阐述见下文. ? Scala中可直接调用Java代码,与Java无缝连接. 语句能够不用";"结束.且推荐不适用";". 变量声明时以var或va

Scala编程--基本类型和操作

如果你熟悉Java,你会很开心地发现Java基本类型和操作符在Scala里有同样的意思.然而即使你是一位资深Java开发者,这里也仍然有一些有趣的差别使得本章值得一读.因为本章提到的一些Scala的方面实质上与Java相同,我们插入了一些注释,Java开发者可以安全跳过,以加快你的进程.本章里,你会获得Scala基本类型的概观,包括String和值类型Int,Long,Short,Byte,Float,Double,Char还有Boolean.你会学到可以在这些类型上执行的操作,包括Scala表

快学Scala 1

  1. Scala解释器读到一个表达式,对它进行求值,将它打印出来,接着再继续读下一个表达式.这个过程被称作“读取-求值-打印-循环”,即REPL.   2. 从技术上来讲,scala程序并不是一个解释器,实际发生的是:你输入的内容被快速地编译成字节码,然后这段字节码交由Java虚拟机执行.   3. 声明值和变量 val answer = 8 * 5 + 2  //val定义常量 answer:Int = 42 var counter = 0 //var声明变量 counter = 1 //

Scala语法学习手册

1       快速入门... 2 1.1             分号... 2 1.2             常变量声明... 2 1.2.1         val常量... 2 1.2.2         var变量... 2 1.2.3         类型推导... 3 1.2.4         函数编程风格... 3 1.3             Range. 3 1.4             定义函数... 4 1.5             while.if 4 1.6