三、变量和类型
常用类型
和Java一样,Scala中也有7种数值类型:Byte、Short、Int、Long、Double、Float、Char,以及1个Boolean类型。跟Java不同的是,这些类型都是类,归属于scala.*
包。还有一种常用类型为java.lang.String
用以声明字符串
表达式
表达式是可计算的语句。如:
1 + 1
你可以使用println
来输出表达式的结果。
// println 打印表达式的值 换行
// print 打印表达式的值 不换行
// 引用表达式的值打印
println(1) // 1
println(1 + 1) // 2
println("Hello!") // Hello!
println("Hello," + " world!") // Hello, world!
声明变量
除了可以重新赋值,变量和常量类似。你可以使用var
关键字来定义一个变量。
var x = 1 + 1
x = 3 // This compiles because "x" is declared with the "var" keyword.
println(x * x) // 9
注意:scala类型可以被推断,或者你也可以显示地声明类型,语法
var x : Int = 10
声明常量(推荐)
你可以使用val
关键字来给表达式的结果命名。
val x = 1 + 1
println(x) // 2
x = 3 // This does not compile.
类型转换
值类型可以按照下面的方向进行转换:
例如:
val x: Long = 987654321
val y: Float = x // 9.8765434E8 (note that some precision is lost in this case)
val face: Char = '☺'
val number: Int = face // 9786
转换是单向,下面这样写将不会通过编译。
val x: Long = 987654321
val y: Float = x // 9.8765434E8
val z: Long = y // Does not conform
你可以将一个类型转换为子类型
运算符
-
算术运算符:
+、-、*、/、%
-
关系运算符:
==、!=、>、<、>=、<=
-
逻辑运算符:
&&、||、!
-
位运算符:
&(按位与)、|(按位或)、^(异或)、~(取反)、<<、>>、>>>(无符号)
2 00000010 3 00000011 2&3=2 00000010 & 同时为1 结果为1 不同为0 2|3=3 00000011 | 有一个为1 结果为1 不同为0 2^3=1 00000001 ^ 相同为0,不同为1 ~2=-3 11111101 2<<1=4 00000100 二进制 向左移动 n位 2>>1=1 >>>
-
赋值运算符:
=
注意:在Scala中,运算符即是方法。
10 + 1
可以写成10.+(1)
Scala类型层次结构【重点】
在Scala中,所有的值都有类型,包括数值和函数。下图阐述了类型层次结构的一个子集。
Any
是所有类型的超类型,也称为顶级类型。它定义了一些通用的方法如equals
、hashCode
和toString
。Any
有两个直接子类:AnyVal
和AnyRef
。AnyVal
代表值类型。有9个预定义的非空的值类型分别是:Double
、Float
、Long
、Int
、Short
、Byte
、Char
、Unit
和Boolean
。Unit
(类似于java中的void
)是不带任何意义的值类型,它仅有一个实例可以像这样声明:()
。所有的函数必须有返回,所以说有时候Unit
也是有用的返回类型。AnyRef
代表引用类型。所有非值类型都被定义为引用类型。在Scala中,每个用户自定义的类型都是AnyRef
的子类型。如果Scala被应用在Java的运行环境中,AnyRef
相当于java.lang.Object
。Nothing
是所有类型的子类型,也称为底部类型。没有一个值是Nothing
类型的。它的用途之一是给出非正常终止的信号,如抛出异常、程序退出或者一个无限循环(可以理解为它是一个不对值进行定义的表达式的类型,或者是一个不能正常返回的方法)。Null
是所有引用类型的子类型(即AnyRef
的任意子类型)。它有一个单例值由关键字null
所定义。Null
主要是使得Scala满足和其他JVM语言的互操作性,但是几乎不应该在Scala代码中使用。我们将在后面的章节中介绍null
的替代方案。
这里有一个例子,说明了字符串、整型、布尔值和函数都是对象,这一点和其他对象一样:
val list: List[Any] = List(
"a string",
732, // an integer
'c', // a character
true, // a boolean value
() => "an anonymous function returning a string"
)
list.foreach(element => println(element))
这里定义了一个类型List<Any>
的变量list
。这个列表里由多种类型进行初始化,但是它们都是scala.Any
的实例,所以可以把它们加入到列表中。
下面是程序的输出:
a string
732
c
true
<function>
四、条件分支
if(布尔表达式 1){
// 如果布尔表达式 1 为 true 则执行该语句块
}else if(布尔表达式 2){
// 如果布尔表达式 2 为 true 则执行该语句块
}else if(布尔表达式 3){
// 如果布尔表达式 3 为 true 则执行该语句块
}else {
// 如果以上条件都为 false 执行该语句块
}
if条件分支
如:
if ( n1 > 0) true
if…else条件分支
如:
val result = if ( n1 > 0) true else false
if…else if … else条件分支
val result = if (n1 > 0) 1
else if(n1 == 0) 0
else -1
注意:
- 代码块中只有一行内容,可以省略
{}
,如有多行代码需用{}
- 代码块的最后一个表达式的值就是块的值
- scala中没有switch语句,不过它有一个强大很多的模式匹配,后续介绍
五、循环
Scala的循环类似于Java的循环
while循环
while(boolean条件){
// 循环体
}
如:求1到100数值之和
// 控制台输入求和值
val input : String = readLine("请输入:")
var num = input.toInt
var sum = 0
while(num > 0){
sum = sum + num
num = num - 1
}
print(sum)
Note : scala中没有
++
和--
,可以使用+=1
或-=1
替换
do … while…循环
do{
//循环体
}while(boolean条件)
如:求1到100数值之和
do {
sum = sum.+(num)
num = num - 1
} while (num > 0)
print(sum)
for循环
Scala没有与Java for循环直接对应的结构,语法如下:
// m to n ,返回m到n(包含m)的Range
for (n <- 1 to 100) {
sum = sum + n
}
print(sum)
// m until n ,返回m到n(不包含m)的Range
for (n <- 1 until 100) {
sum = sum + n
}
print(sum)
嵌套for循环
如:九九乘法表
// 传统方式
for (m <- 1 to 9) {
for (n <- 1 to m) {
print(s"$m*$n=" + m * n + "\t")
if (m == n) println
}
}
// 推荐方式:多层循环用”;“分隔
for (m <- 1 to 9; n <- 1 to m) {
print(s"$m*$n=" + m * n + "\t")
if (m == n) println
}
for遍历集合
val list = List[String]("Hello World", "Hello Hadoop")
for (str <- list) {
println(str)
}
for循环过滤(if守卫)
if作为for守卫语句能实现过滤的效果,显著地降低循环次数,并且更易读,如下:
for (n <- 1 to 10 if n % 2 == 0 if n > 5) {
println(s"$n")
}
// 6 8 10
yield
for 循环中的 yield 会把当前的元素记下来,保存在集合中,循环结束后将返回该集合
- 针对每一次 for 循环的迭代, yield 会产生一个值,被循环记录下来 (内部实现上,像是一个缓冲区).
- 当循环结束后, 会返回所有 yield 的值组成的集合.
- 返回集合的类型与被遍历的集合类型是一致的.
val result = for (n <- 1 to 10 if n % 2 == 1 if n != 5) yield n * 2
println(result)
//Vector(2, 6, 14, 18)
// 如果您愿意:也可以将生成器、守卫和定义包含在花括号中,并以换行的方式分隔
val result = for {n <- 1 to 10
if n % 2 == 1
if n != 5}yield n * 2
println(result)
Break
Scala中没有提供break和continue关键词来退出循环,可以使用Breaks对象中的break方法终止循环
import scala.util.control.Breaks._
breakable {
for (n <- 1 to 10) {
if (n == 5) break
println(n)
}
}