Scala编程实例:使用List和Tuple
本节接着上一节的内容,继续介绍Scala编程中一些更先进的特征:List(数组)和Tuple(元组)。
Scala中使用List
方法不应该有副作用是函数风格编程的一个很重要的理念。方法唯一的效果应该是计算并返回值。用这种方式工作的好处就是方法之间很少纠缠在一起,因此就更加可靠和可重用。另一个好处(静态类型语言里)是传入传出方法的所有东西都被类型检查器检查,因此逻辑错误会更有可能把自己表现为类型错误。把这个函数式编程的哲学应用到对象世界里意味着使对象不可变。
如你所见,Scala数组是一个所有对象都共享相同类型的可变序列。比方说Array[String]仅包含String。尽管实例化之后你无法改变Array的长度,它的元素值却是可变的。因此,Array是可变的对象。
说到共享相同类型的不可变对象序列,Scala的List类才是。和数组一样,List[String]包含的仅仅是String。Scala的List,scala.List,不同于Java的java.util.List,总是不可变的(而Java的List可变)。更通常的说法,Scala的List是设计给函数式风格的编程用的。
创建一个List很简单。代码3.3做了展示:
- val oneTwoThree = List(1, 2, 3)
代码 3.3 创造和初始化列表
代码3.3中的代码完成了一个新的叫做oneTwoThree的val,并已经用带有整数元素值1,2和3的新List[Int]初始化。 因为List是不可变的,他们表现得有些像Java的String:当你在一个List上调用方法时,似乎这个名字指代的List看上去被改变了,而实际上它只是用新的值创建了一个List并返回。比方说,List有个叫“:::”的方法实现叠加功能。你可以这么用:
- val oneTwo = List(1, 2)
- val threeFour = List(3, 4)
- val oneTwooneTwoThreeFour = oneTwo ::: threeFour
- println(oneTwo + " and " + threeFour + " were not mutated.")
- println("Thus, " + oneTwoThreeFour + " is a new List.")
如果你执行这个脚本,你会看到:
- List(1, 2) and List(3, 4) were not mutated.
- Thus, List(1, 2, 3, 4) is a new List.
或许List最常用的操作符是发音为“cons”的‘::’。Cons把一个新元素组合到已有List的最前端,然后返回结果List。例如,若执行这个脚本:
- val twoThree = list(2, 3)
- val oneTwoThree = 1 :: twoThree
- println(oneTwoThree)
你会看到:
- List(1, 2, 3)
注意
表达式“1 :: twoThree”中,::是它右操作数,列表twoThree,的方法。你或许会疑惑::方法的关联性上有什么东西搞错了,不过这只是一个简单的需记住的规则:如果一个方法被用作操作符标注,如a * b,那么方法被左操作数调用,就像a.*(b)——除非方法名以冒号结尾。这种情况下,方法被右操作数调用。因此,1 :: twoThree里,::方法被twoThree调用,传入1,像这样:twoThree.::(1)。
5.8节中将描述更多操作符关联性的细节。
由于定义空类的捷径是Nil,所以一种初始化新List的方法是把所有元素用cons操作符串起来,Nil作为最后一个元素。
比方说,下面的脚本将产生与之前那个同样的输出
- “List(1, 2, 3)”:
- val oneTwoThree = 1 :: 2 :: 3 :: Nil
- println(oneTwoThree)
Scala的List包装了很多有用的方法,表格3.1罗列了其中的一些。列表的全部实力将在第十六章释放。
为什么列表不支持append?
类List没有提供append操作,因为随着列表变长append的耗时将呈线性增长,而使用::做前缀则仅花费常量时间。如果你想通过添加元素来构造列表,你的选择是把它们前缀进去,当你完成之后再调用reverse;或使用ListBuffer,一种提供append操作的可变列表,当你完成之后调用toList。ListBuffer将在22.2节中描述。
Scala中使用Tuple
另一种有用的容器对象是元组:tuple。与列表一样,元组也是不可变的,但与列表不同,元组可以包含不同类型的元素。而列表应该是List[Int]或List[String]的样子,元组可以同时拥有Int和String。元组很有用,比方说,如果你需要在方法里返回多个对象。Java里你将经常创建一个JavaBean样子的类去装多个返回值,Scala里你可以简单地返回一个元组。而且这么做的确简单:实例化一个装有一些对象的新元组,只要把这些对象放在括号里,并用逗号分隔即可。一旦你已经实例化了一个元组,你可以用点号,下划线和一个基于1的元素索引访问它。代码3.4展示了一个例子:
- val pair = (99, "Luftballons")
- println(pair._1)
- println(pair._2)
代码 3.4 创造和使用元组
代码3.4的第一行,你创建了元组,它的第一个元素是以99为值的Int,第二个是"luftballons"为值的String。Scala推断元组类型为Tuple2[Int, String],并把它赋给变量pair。第二行,你访问_1字段,从而输出第一个元素,99。第二行的这个“.”与你用来访问字段或调用方法的点没有区别。本例中你正用来访问名叫_1的字段。如果执行这个脚本,你能看到:
- 99
- Luftballons
元组的实际类型取决于它含有的元素数量和这些元素的类型。因此,(99, "Luftballons")的类型是Tuple2[Int, String]。('u', 'r', 'the', 1, 4, "me")是Tuple6[Char, Char, String, Int, Int, String]。
访问元组的元素
你或许想知道为什么你不能像访问List里的元素那样访问元组的,就像pair(0)。那是因为List的apply方法始终返回同样的类型,但是元组里的或许类型不同。_1可以有一个结果类型,_2是另外一个,诸如此类。这些_N数字是基于1的,而不是基于0的,因为对于拥有静态类型元组的其他语言,如Haskell和ML,从1开始是传统的设定。
本文节选自《Programming in Scala》
【相关阅读】
- Scala编程实例:带类型的参数化数组
- 初探Scala编程:编写脚本,循环与枚举
- 初探Scala编程:解释器,变量及函数定义
- 影响Scala语言设计的因素列表
- 喜欢Scala编程的四个理由
转自:http://developer.51cto.com/art/200907/134954.htm
转载于:https://www.cnblogs.com/captainlucky/p/4535366.html
Scala编程实例:使用List和Tuple相关推荐
- Scala编程——下界介绍与实例分析
最近又在重温Scala编程.上bilibili网站看了韩顺平老师在尚硅谷的Scala编程语言的教学视频.发现韩老师有关Scala下界的介绍与示例说明,讲解的不是很清晰.并认为可能会给一些学习Scala ...
- 函数式编程实例WordCount(林子雨老师慕课代码) 由于文件引入的问题之前报过Exception in thread “main“ java.lang.NullPointerExcept(已解决)
函数式编程实例WordCount 数据文件目录: 文件内容: 刚开始在写文件的时候以为val dirfile = new File("data")这一行写的是具体文件,于是我写成了 ...
- 第二章:《RDD编程实例之 实验报告》
一.函数式编程实例WordCount 任务:按照函数式编程的风格,编写一个程序,对某个目录下所有文件中的单词进行词频统计 做法:请进入Linux系统,打开"终端",进入Shell命 ...
- Scala编程基础——集合高阶函数
Scala编程基础--集合&高阶函数 集合 Scala中集合分为可变集合和不可变集合 可变集合:可以修改.添加.移除一个集合的元素. 不可变集合:安全的并发访问. 不可变集合,相比之下,永远不 ...
- 【Akka】Akka入门编程实例
引言 这篇文章主要是第一次学习Akka编程,先试试水,探探坑,对Akka和SBT的使用有一个直观的了解,以几个简单的akka编程实例来说明akka的使用.希望在日后的学习和编程中,能有更多自己的体会和 ...
- Scala 编程基础 C(函数式编程)
文章目录 1. 函数定义和高阶函数 2. 针对集合的操作 3. 函数式编程实例:WordCount 1. 函数定义和高阶函数 Scala是一门多范式编程语言,混合了面向对象编程和函数式编程的风格.在过 ...
- Python并发编程实例教程
有关Python中的并发编程实例,主要是对Threading模块的应用,文中自定义了一个Threading类库. 一.简介 我们将一个正在运行的程序称为进程.每个进程都有它自己的系统状态,包含内存状态 ...
- iOS网络编程-iCloud键值数据存储编程实例
iCloud键值数据存储设计 iCloud键值数据存储编程实例,画面中有两个开关控件,左图是设备1点击"设置iCloud数据"按钮,将控件状态保存到iCloud服务器.右图是设备2 ...
- NIO Socket编程实例
1.阻塞模式实例 NIOUtil类,用来通过SOcket获取BufferedReader和PrintWriter. package IO;import java.io.BufferedReader; ...
- 大数据Scala编程.问题集(02)
大数据Scala编程.问题集(02) by 高焕堂 洞庭国际智能硬件检测基地 & 中云大数据中心(IDC) 首席架构师 微博:@高焕堂_台北 Q-02: Scala语言的trait具有什么设计 ...
最新文章
- 天天都在说,无服务器计算到底是什么?
- 提取一个二进制位最右侧的1
- 100题_08 求1+2+...+n
- js 对已知数组数据的导出EXCEL
- ocLazyLoad angular 按需加载
- Python运算符优先级
- 服务器改用ssh文件登录
- axios vue 回调函数_VUE使用axios调用后台API接口的方法
- mysql查询表变量_MySQL 之SQL语言、表库操作、查询及变量精讲
- Java中的泛型使用
- 【机器学习-西瓜书】三、线性回归;对数线性回归
- excel 某个单元格不是等于空值_将数据合并到一个单元格,用函数也OK
- 《中国AI算力发展评估报告》发布!北京只能排第二,推理需求猛增
- image 搜索docker_docker images命令-列出image
- Linux驱动之定时器(mod_timer)
- ToDesk 远程软件推荐测评
- Mybatis在XML中写SQL比较运算符<=时报错解决方法
- matlab 误差修正模型,求问大神用R做VEC(误差修正)模型的程序包或者代码是什么啊?...
- 小米路由器R1C或R1CM小米R1C 原厂Bootloader和epproom
- delphi 剪切板变量_Delphi监视剪贴板内容