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》
【相关阅读】
转自:http://developer.51cto.com/art/200907/134954.htm
Scala编程实例:使用List和Tuple的更多相关文章
- SCALA编程实例
SCALA与JAVA很相似,包括类.函数.集合等等的使用.如果你是一个JAVA程序员,你应该会很快上手. 需要注意的是SCALA特有的一些奇葩标志,比如->,比如=>,遇到要注意下. 使用 ...
- Scala 编程(一)Scala 编程总览
Scala 简介 Scala 属于“可伸展语言”,源于它可以随使用者的需求而改变和成长.Scala 可以应用在很大范围的编程任务上,小到脚本大到建立系统均可以. Scala 跑在标准 Java 平台上 ...
- Scala编程进阶
跳出循环语句的3种方法... 2 多维数组... 3 Java数组与Scala数组缓冲的隐式转换... 3 Java Map与Scala Map的隐式转换... 3 Tuple拉链操作... 4 内部 ...
- Scala编程基础
Scala与Java的关系... 4 安装Scala. 4 Scala解释器的使用... 4 声明变量... 5 数据类型与操作符... 5 函数调用与apply()函数... 5 if表达式... ...
- (升级版)Spark从入门到精通(Scala编程、案例实战、高级特性、Spark内核源码剖析、Hadoop高端)
本课程主要讲解目前大数据领域最热门.最火爆.最有前景的技术——Spark.在本课程中,会从浅入深,基于大量案例实战,深度剖析和讲解Spark,并且会包含完全从企业真实复杂业务需求中抽取出的案例实战.课 ...
- Scala编程 笔记
date: 2019-08-07 11:15:00 updated: 2019-11-25 20:00:00 Scala编程 笔记 1. makeRDD 和 parallelize 生成 RDD de ...
- PHP多进程编程实例
这篇文章主要介绍了PHP多进程编程实例,本文讲解的是在Linux下实现PHP多进程编程,需要的朋友可以参考下 羡慕火影忍者里鸣人的影分身么?没错,PHP程序是可以开动影分身的!想完成任务,又觉得一个进 ...
- c#摄像头编程实例 (转)
c#摄像头编程实例 摄像头编程 安装摄像头后,一般可以找到一个avicap32.dll文件 这是一个关于设想头的类 using system;using System.Runtime.Intero ...
- JAX-RS 2.0 REST客户端编程实例
JAX-RS 2.0 REST客户端编程实例 2014/01/28 | 分类: 基础技术, 教程 | 0 条评论 | 标签: JAX-RS, RESTFUL 分享到:3 本文由 ImportNew - ...
随机推荐
- 和为S的连续正数序列★★
题目描述 小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100.但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数).没多久,他 ...
- 【转】让Entity Framework不再私闯sys.databases
这里的“私闯sys.databases”是指Entity Framework默认发起的查询:SELECT Count(*) FROM sys.databases WHERE [name]=N'数据库名 ...
- 【原】Ajax技术原理
主要内容: Ajax原理 Ajax核心技术 Ajax是Asynchronous JavaScript and XML的简称,意思是异步的JavaScript和XML. 主要包括技术: web标准的XH ...
- 标准Trie字典树学习二:Java实现方式之一
特别声明: 博文主要是学习过程中的知识整理,以便之后的查阅回顾.部分内容来源于网络(如有摘录未标注请指出).内容如有差错,也欢迎指正! 系列文章: 1. 标准Trie字典树学习一:原理解析 2.标准T ...
- Hadoop学习笔记(10) ——搭建源码学习环境
Hadoop学习笔记(10) ——搭建源码学习环境 上一章中,我们对整个hadoop的目录及源码目录有了一个初步的了解,接下来计划深入学习一下这头神象作品了.但是看代码用什么,难不成gedit?,单步 ...
- [linux] shell脚本编程-ubuntu创建vsftpd服务
1. useradd -s /bin/bash -m 用户名 , 创建用户,自动创建家目录 , 设置登录shell 2. echo 用户名:密码 | chpasswd ,非交互式设置密码 3. ...
- Spring MVC 实现Excel的导入导出功能(1:Excel的导入)
简介 这篇文章主要记录自己学习上传和导出Excel时的一些心得,企业办公系统的开发中,经常会收到这样的需求:批量录入数据.数据报表使用 Excel 打开,或者职能部门同事要打印 Excel 文件,而他 ...
- redis集群的远程管理与监控
一.redis集群的重要性 目前大部分的互联网平台,都会用到Redis内存数据库,以提高响应速度,提升用户使用体验. 为了实现Redis的高可用,通常都会布署Redis集群,使用Redis-Senti ...
- Web安全相关(三):开放重定向(Open Redirection)
简介 那些通过请求(如查询字符串和表单数据)指定重定向URL的Web程序可能会被篡改,而把用户重定向到外部的恶意URL.这种篡改就被称为开发重定向攻击. 场景分析 假设有一个正规网站http://ne ...
- 20个网页设计师应该学习的CSS3经典教程实例
CSS3技术离我们越近,我们也应该学习一些简单的CSS3技术了,而学习最基本的方法就是模仿,以及观看大师作品的案例.收集了20个基础教程,均是涉及到css3应用范围,值得你和我一起共同学习. Smoo ...