版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
文章目录
1. 变量声明
Scala的变量分为两种:val和var。
val跟Java的final变量类似,一旦初始化就不能被重新赋值。
var可以被重新赋值。
变量声明时,可指定类型,也可不用指定类型(此时会自动推断类型)
// val声明变量
val str01:String = "Hello World"
val str02 = "str02"
// str02 = "str00" 会编译错误
// var声明变量
var str03 = "str03"
str03 = "aaa" // 不会编译错误
Scala程序的变量在声明时附带了作用域,花括号一般都会引入一个新的作用域。
关于作用域,Scala和Java的区别是,Java不允许在内嵌的作用域使用一个跟外部作用域内相同名称的变量,但是Scala中内嵌作用域中的变量会遮挡外部作用域中相同名称的变量,因此外部作用域同名变量在内嵌作用域中不可见。
2. 数据类型
2.1 基础类型
和Java较一致。
- Byte:8位带符号二进制补码整数
- Short:16位带符号二进制补码整数
- Int:32位带符号二进制补码整数
- Long:64位带符号二进制补码整数
- Char:16位无符号Unicode字符
- Float:32位IEEE 754单精度浮点数
- Double:64位IEEE 754双精度浮点数
- Boolean:true或false
- String:Char的序列
2.2 字面量
- 整数字面量
Int、Long、Short、Byte的整数字面量有两种形式:十进制和十六进制,不同开头表示了不同的进制。十六进制:以0x或0X开头,可以包含0~9以及大写或小写的A ~ F。
如果整数字面量以l或L结尾,那么就是Long类型的,否则就是Int。 - 浮点数字面量
由十进制的数字、可选小数点,以及后续一个可选的E或e打头的指数组成。例如 1.2345e2。
付过浮点数字面量以F或f结尾,那它就是Float类型的,否则就是Double类型。Double可以以D或d结尾,但这个可选。 - 字符字面量
由一对单引号和中间的任意Unicode字符组成。除了显示给出原字符,也可以用字符的Unicode码来表示,具体就是 \u 加上 Unicode码对应的4位的十六进制数字,例如:val d = ‘\u0041’。 - 字符串字面量
由双引号包起来的字符组成。
如果不想写大量的转义序列或者跨对行的字符串,可以使用三个双引号开始并以三个双引号结束来表示原生字符串,原生字符串内部可以包含任何字符,包括换行、单双引号和其他特殊字符。
var a = """ Welcome to here.
I am very glad to see you."""
println(a)
打印结果:
Welcome to here.
I am very glad to see you.
问题在于:字符串第二行前面的空格被包含进去,为了解决这个问题,可以每行开始加一个管道符|,然后对字符串调用stripMargin方法,如下。
var a = """Welcome to here.
|I am very glad to see you.""".stripMargin
println(a)
打印结果:
Welcome to here.
I am very glad to see you.
2.3 字符串插值
- s插值器:处理变量
- raw插值器:处理特殊字符
- f插值器:给内嵌的表达式加上printf风格的指令,指令放在表达式之后,以百分号%开始
val name = "Jason"
println(s"Hello, $name") // Hello, Jason
println(s"The answer is ${6*7}") // The answer is 42
println(raw"Hello\\\\World") // Hello\\\\World
println(f"${Math.PI}%.5f") // 3.14159
3. 操作符
3.1 传统意义操作符在Scala中的理解
Scala实际上并没有传统意义上的操作符。类似+、-、*、/ 这样的字符可以被用作方法名。例如 1+2 实际上是调用了Int对象1上名为+的方法,将2作为参数传入,即 1.+(2),Int有多个重载的+方法,可以分别接收不同的参数类型。
整数之间使用 / ,只会保留结果的整数部分,并且不会进行四舍五入。
- 算数运算符:+ - * / %
- 关系和逻辑运算符:> < >= <= !
- 逻辑运算符:&&或&,||或| 。&&和||是短路的,在左侧已经确定了表达式结果的情况下不会对右侧进行求值。
- 位运算符:& | ^ ~ >>(右移,用左侧值最高位(符号位)来填充) >>>(无符号右移,自动填充0) <<(左移,自动填充0)
- 对象相等性: == !=
println(1==1.0) //true
,Scala的 == 跟 Java的不同,Scala中只要内容一致就返回true
3.2 Scala中的操作符
Scala中的操作符表示法并不局限于其他语言中看上去像操作符的方法,可以在操作符表示法中使用任何方法。例如 String类有一个indexOf方法,可以这么用
val str = "Hello World"
println(str indexOf 'e') // 1
println(str indexOf ('o',5)) // 7
3.3 前缀、中缀、后缀操作符
上面举的一些例子都是中缀操作符。前缀表示法需要将方法名放在调用的方法的对象前面,后缀相反
前缀操作符其实是调用的方法 "unary_"加上操作符,例如-2.0实际是 (2.0).unary_-。唯一能被用作前缀操作符的是 +、-、! 和 ~
// 前缀
val a = (2.0).unary_-
// 后缀
val b = "Hello World" toLowerCase()
println(a) // -2.0
println(b) // hello world
4. 控制结构
Scala只有为数不多的几个内建的控制结构,包括:if、while、do…while、for、try、match 和函数调用。
Scala所有的控制结构都返回某种值作为结果。
4.1 if
if可以返回具体结果
4.2 while / do…while
while、do…while返回单位值Unit—()
4.3 for
- for表达式可以添加过滤器,是表达式的圆括号中的一个if子句,也可以添加多个过滤器。
val filesHere = new File("D:\\MyProject").listFiles
// 单个过滤器
for(file <- filesHere if !file.getName.endsWith(".scala"))
println(file)
// 多个过滤器
for(file <- filesHere
if file.isFile
if !file.getName.endsWith(".scala"))
println(file)
- 嵌套迭代
val fileHere = new File(".").listFiles()
def fileLines(file: File) = scala.io.Source.fromFile(file).getLines().toList
def grep(pattern: String) =
for (
file <- fileHere
if file.getName.endsWith(".scala");
line <- fileLines(file);
trimLine = line.trim
if trimLine.matches(pattern)
) println(file + ":" + trimLine)
grep(".*gcd.*")
- 通过关键字
yield
返回列表
格式:for 子句 yield 代码体
val res = for (i <- 0 to 3) yield {
i * i
}
println(res.mkString(",")) // 0,1,4,9