《快学Scala》——控制结构和函数
条件表达式
在Scala中if/else表达式有值,这个值就是跟在if或else之后的表达式的值。例如:
if (x > 0) 1 else -1上述表达式的值是1或-1,具体是哪一个取决于x的值。你可以将if/else的值赋值给变量:
val s = if (x > 0) 1 else -1这与如下语句的效果一致:
if (x > 0) s = 1 else s = -1以上两个的区别在于:第一个可以用来初始化val;第二种s必须是var。
在Scala中每个表达式都有一个类型。如:
if (x > 0) 1 else -1的类型是Int,因为两个分支的类型是Int。当两个分支的类型不同时,那该表达式的类型就是两个分支类型的公共超类型。注:Scala里,每个类都继承自通用的名为Any的超类。因为所有的类都是Any的子类,所以定义在Any中的方法就是“共同的”方法:它们可以被任何对象调用。Scala还在层级的底端定义了一些类,如Null和Nothing,扮演通用的子类。即,Any是所有其他类的超类,Nothing是所有其他类的子类。
如果else部分缺失,比如
if (x > 0) 1,那么该表达式可能没有输出值。但是在Scala中,每个表达式都应该有值。所以在Scala中引入了Unit类,写做()。那么上面的表达式就等同于if (x > 0) 1 else ()。
块表达式和赋值
在Scala中,{}块包含一系列表达式,其结果也是一个表达式。块的最后一个表达式的值就是块的值。如下:
val z = {val x = 2; val y = 4; x * y} //结果z = x * y = 8在Scala中,赋值动作本身是没有值的,或者更严格的说他们的值是Unit类型的。如
{r = r * n; n -= 1}的值就是Unit类型的。
注:由于赋值语句的值是Unit类型的,故不能将它们串联起来。如x = y = 1,这里y = 1的值是()。
输入和输出
- 输出:用print和println这和Java类似。
输入:可以用readLine函数读取控制台上的一行输入。也可以用readInt、readDouble、readByte、readShort、readLong、readFloat、readBoolean或者readChar。和其他方法的区别是,readLine带有一个参数作为提示字符串。如下:
val name = readLine("Your name:") print("Your age:") val age = readInt()
循环
Scala中的使用循环有两种选择:
while:
while (n > 0) { r = r * n n -= 1 }for:
for(i <- 表达式)for(i <- 1 to n) r = r * i注:在for循环的变量之前并没有val和var的指定。该变量的类型是集合的元素类型。循环变量的作用域一直持续到循环结束。
当for循环在遍历字符串和数组时,需要使用until方法而不是to方法。to方法返回包含上限的闭区间,until方法返回一个不包含上限的区间。如下遍历字符串的例子:
//方法一 val s = "Hello" var sum = 0 for(i <- 0 until s.length) sum +=s(i) //方法二 var sum = 0 for(ch <- "Hello") sum += ch
注:Scala不提供break或continue来退出循环,退出循环的方法如下:
- 使用Boolean型的控制变量。
- 使用嵌套函数,从函数中return。
- 使用Breaks对象的break方法。
高级for循环和for推导式
可以使用变量<-表达式的形式提供多个生成器,用分号将它们隔开。例如:
for(i <- 1 to 3; j <- 1 to 3) print((10 * i + j) + " ") //将打印11 12 13 21 22 23 31 32 33每个生成器都可以带一个守卫,以if开头的Boolean表达式。注意if前没有分号例如:
for(i <- 1 to 3; j <- 1 to 3 if i != j) print((10 * i + j) + " ") //将打印12 13 21 23 31 32如果for循环的循环体使用yield开始,则该循环会构造出一个集合,每次迭代生成集合中的一个值。这类循环成为for推导式。例如:
for(i <- 1 to 10) yield i % 3 //生成 Vector(1, 2, 0, 1, 2, 0, 1, 2, 0, 1)其中for推导式生成的集合与它的第一个生成器是类型兼容的。如下图:

函数
Scala除了方法外还支持函数。方法对对象进行操作,函数不是。要定义函数,必须给出函数名、参数和函数体。如下:
def abs(x: Double) = if(x > 0) x else -x必须给定所有参数的类型,只要函数不是递归的,就不用指定返回类型。如果函数体需要多个表达式,可以使用代码块,块中最后一个表达式的值就是函数的返回值。
默认参数和带名参数
def decorate(str: String, left: String = "[", right:String = "]") = left + str + right
//调用函数如下
decorate("Hello") //输出 [Hello]
decorate("Hello", "%%%") //输出 %%%Hello]
decorate(left = "[", str = "Hello", right = "]") //输出 [Hello]
decorate("Hello",right = "****[") //输出 [Hello***]
decorate("<<","Hello",right = ">>>") //输出 Hello<<>>>
从上例可以看出left和right是默认参数,如果不喜欢默认值就可以在调用的时候重新赋值。我们可以在提供参数值时带上参数名,这个时候参数列表的顺序可以变。当我们混用未命名参数和带名参数时,需要将未命名参数排在前面,并将未命名参数按照参数列表的顺序排放。
过程
Scala中如果函数体包含在花括号当中但没有前面的=号,那么返回类型应该是Unit。这样的函数被称作过程。
懒值
当val被声明为lazy时,它的初始化将被推迟,直到首次使用时才取值。
参考文献
《快学Scala》——控制结构和函数的更多相关文章
- 《快学Scala》
Robert Peng's Blog - https://mr-dai.github.io/ <快学Scala>Intro与第1章 - https://mr-dai.github.io/S ...
- 快学Scala习题解答—第一章 基础
1 简介 近期对Scala比较感兴趣,买了本<快学Scala>,感觉不错.比<Programming Scala:Tackle Multi-Core Complexity on th ...
- 2.scala控制结构、函数、异常处理
2.scala控制结构.函数.异常处理---小书匠,在线编辑器,MARKDOWN,Evernote,文件版本 a:focus { outline: thin dotted #333; outline: ...
- 快学Scala 第十九课 (trait的abstract override使用)
trait的abstract override使用: 当我看到abstract override介绍的时候也是一脸懵逼,因为快学scala,只介绍了因为TimestampLogger中调用的super ...
- 快学Scala 2
控制结构和函数 1.在Scala中,几乎所有构造出来的语法结构都有值.这个特性是为了使得程序更加精简,也更易读. (1)if表达式有值 (2)块也有值——是它最后一个表达式的值 (3)Scala的fo ...
- [Scala] 快学Scala A1L1
基础 1.1 声明值和变量 在Scala中,鼓励使用val; 不需要给出值或变量的类型,这个信息可以从初始化表达式推断出来.在必要的时候,可以指定类型. 在Scala中,仅当同一行代码中存在多条语句时 ...
- 快学scala
scala 1. scala的由来 scala是一门多范式的编程语言,一种类似java的编程语言[2] ,设计初衷是要集成面向对象编程和函数式编程的各种特性. java和c++的进化速度已经大不如 ...
- 《快学scala》读书笔记(2)
第二章 控制结构和函数 1.条件表达式 (1)scala中if/else表达式有值,这个值就是跟在if或者else之后的表达式的值.如: if (x > 0) 1 else -1 这个表达式的 ...
- 《快学Scala》——基础
声明值和变量 用val定义的值实际上是常量.用var定义的值是变量.在scala中鼓励使用val.不需要给出值或变量的类型,这个信息可以通过初始化的表达式推断出来.(声明值和变量但不做初始化会报错) ...
- 快学 Scala 入门 3 部曲
1 基础 1.1 Scala 解释器 REPL - 交互式解释器环境 R(read).E(evaluate).P(print).L(loop) 输入值,交互式解释器会读取输入内容并对它求值,再返回结果 ...
随机推荐
- fastlane安装流程和fastlane match同步证书和PP文件方法
分步指南 安装fastlane: ① Make sure you have the latest version of the Xcode command line tools installed: ...
- Windows:将cmd命令行添加到右键中方法
win10中将命令行cmd添加到右键的方法 Windows cmd 右键 win10 命令行 最近在学python,所以会用到很多库文件,但是有的库文件需要下载whl文件再通过cmd进行安装,所以每次 ...
- Java单例模式再加强——按组多单例
最近要使用alibaba的rocket mq(我们公司对其进行了封装,使其运行在dotNet平台上,Java还是和原生的差不多,涉及公司的内容本文不会提及),其中 在生产者组这一块,建议是用单例模式的 ...
- 一个关于Python正则表达式的快速使用手册
一直在纠结自己的博客到底应该写一些什么东西,这几天发现自己的正则用的不是很熟练,于是想要写一篇关于正则表达式的博客,目的就是为了让自己以后要用而又不会的时候不至于像无头苍蝇一样到处乱撞. 有些人在碰到 ...
- Ubuntu 16.04 设置MySQL远程访问权限
本文记录一下在Ubuntu 16.04版本下设置MySQL数据库的远程访问. 第一步:修改配置文件的端口绑定 打开的目录可能会根据MySQL的版本稍有不同,可以先尝试打开/etc/mysql/my.c ...
- Visual Studio Code 使用Chrome Debug 代码
一.添加插件 Debugger for Chrome,点击安装,安装完成之后,启动 二.配置启动参数 1.按 F5,出现界面如图,选择 Chrome 2.然后会打开配置文件 launch.json 3 ...
- 老李分享:Robotium编写测试用例如何模拟Junit4的BeforeClass和AfterClass方法1 - 条件判断法
老李分享:Robotium编写测试用例如何模拟Junit4的BeforeClass和AfterClass方法1 - 条件判断法 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜 ...
- 老李分享:走读unittest源码
老李分享:走读unittest源码 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.poptest测试开发工程师就业培训感兴趣 ...
- Android 用 camera2 API 自定义相机
前言 笔者因为项目需要自定义相机,所以了解了一下 Android 关于 camera 这块的 API.Android SDK 21(LOLLIPOP) 开始已经弃用了之前的 Camera 类,提供了 ...
- Andorid自动读取短信验证码
手机收到验证码短信后,程序自动识别验证码并填充验证码输入框. 思路是有了,实现的方式也有多种: 1.开启一个线程,隔一段时间就去查询收件箱是否有变化,有变化再读取出来做处理. 2.注册一个短信变化的广 ...