Scala基础应用(1)- 基本语法
本章主要讲解Scala基本语法,如何定义变量,函数,基本控制结构等。
1. 解释器
Scala可以像其它脚本语言一样,边解释边运行,但实际项目中一定是通过编译后再运行
- 安装好Scala后,在控制台运行scala即进入解释器环境
- 另外可以在scala后面加上scala脚本文件,也可直接执行脚本
- 解释器可以多行输入,按两次回车退回编写
- 输入:quit 或者 :q 退出解释器
2. 变量定义
- 变量有两种:var 和 val, 其中var定义的变量可以重新赋值,val定义的变量是只读的,不可重新赋值。
- var和val定义的变量可以进行类型推断,如C#中的var
变量定义样式:
var或者val 变量名: 类型 = 初始值 如: var variableName1: String = "hello world!" val variableName2: String = "hello world!"
3. 函数定义
函数定义的样式如下:
def 函数名(变量1:类型, 变量2: 类型): 返回类型 = { 函数体 }
如果函数体可以用一行写完,可以省略大括号
如: def max(x: Int, y: Int) = if (x >y) x else y
函数字面量 (literal)
函数字面量可以理解为Java/C#的匿名函数,样式如下: (变量1: 类型, 变量2: 类型) => { 函数体 } 同理这里的大括号里的函数体如果一行可以写完,也可以省略大括号 函数字面量的实际工作原理是:编译器会将函数字面量展开为一个继承自scala.FunctionN的内部类 例: val test = (x: String) => x 其它字面量与Java一样,有Java经验的可以略过,但要了解Symbol字段量 如: def test(r: Symbol) { println(r) } test('mytest)
4. 基本控制
4.1 if
样式
if (条件) { 执行体 } else { 执行体 }
注意:scala里的表达式都有返回值,如:
val hello = if (args.isEmpty) "empty" else args(0)
4.2 While
样式
while(条件) { 执行体 } 如: var i = 0 while (i < 10) { println(i) }
注意: 这样写while循环是指令式(imperative)编程,如C#, Java…, scala允许使用指令式编程,但scala更倾向于一种更为函数式的编程风格。
4.3 do-while
样式
do { 执行体 } while (条件) do-while 与while很类似,只是把条件写在最后
4.4 for
4.4.1 遍历集合
样式
for (变量 <- 集合) { 执行体 } 同理,如果执行体一行可以写完,大括号也可以省略 例: for (c <- "this is a test string") println(c) 记住,变量c是val, 执行体里不可以重新赋值
4.4.2 过滤
样式
for (变量 <- 集合 if 条件1; if 条件2) { 执行体 } 如: for (c <- "this is a test string" if c == 't') println(c)
4.4.3 嵌套枚举
样式
for (变量1 <- 集合1 if 条件1; if 条件2; 变量2 <- 集合2 if 条件3; if 条件4) { 执行体 } 如: for { c <- "this is a test string" if c == 't' || c == 's' s <- c.toString if s == 't' } println (s)
注意,if 条件后面的分号, 这里for后面的小括号可以使用大括号,好处是不用写分号
4.4.4 流间(mid-stream)变量绑定
直接上代码:
for {
c <- "this is a test string"
if c == 't' || c == 's'
str = c.toString // 流间变量也是val
s <- str
if s == 't'
} println (s)
4.4.5 制造新集合
样式
for {子句} yield { 执行体 } 如: val result = for { c <- "this is a test string" if c == 't' || c == 's' str = c.toString // 流间变量也是val s <- str if s == 't' } yield s for(c <- result) println (c)
4.5 foreach
在scala里,很多类都有foreach函数,使用方法如下:
变量.foreach(函数)
如:
"this is a test.".foreach(println)
5. 异常处理
- 抛出异常与Java一样, 如: throw new IllegalArgumentException
捕获异常
样式: try { 执行体 } catch { case ex: 异常类型1 => 执行体 case ex: 异常类型2 => 执行体 } finally { 执行体 } 与java的区别: 不需要throws 另外, try-catch-finally 与其它控制结构一样有返回值, 并且与 java有区别是finally低于try执行体的返回值,所以尽量不在finally里返回值
6. match
match 类似于Java/C#中的switch, 但match的case范围更广泛,几乎可以case所有值
样式
变量 match { case 值1 => 执行体 case 值2 => 执行体 case _ => 执行体 }
7. 包
样式
package 包名1 { 定义体 package 包名2 { 定义体 } } 包的声明有点类似于C#的namespace的声明方式,允许嵌
8.引用
样式
import 包名.类 / import 包名.变量 // 引用某个类或变量 import 包名._ / import 包名.{_} // 引用包或类下面所有的定义, 这两个声明同义 import 包名.{类或变量} // 只引用类,或类成员 import 包.{<原始名> => <新名>} // 引用包/类/变量,并重命名 import 包.{<原始名> => _, _} // 引用包下所有成员,但<原始名>对应的成员除外
几个内建引用
import java.lang._ // java.lang包的所有成员 import scala._ // scala包的所有成员 import Preder._ // Predef对旬的所有成员
9. 访问修饰符
- private: 私有
- protected: 只能在子类中访问,同一个包的其它类不可以访问。 (与java不同)
- public: 缺省下,所有没有加访问修饰符的成员都是public的,而且不用显示声明