一、变量
1、三种变量修饰符
val 定义 immutable variable(不修改 常量)
var 定义 immutable variable(可修改 变量)
lazy val (惰性赋值的常量):不直接算出结果,在系统第一次调用 lazy val 的时候计算结果
scala> val d = 12 d: Int = 12 scala> val e = 20 e: Int = 20 scala> lazy val f = d * e f: Int = <lazy> scala> f*12 res41: Int = 2880 scala> f res42: Int = 240
* 可以不显示指定变量的类型,因为Scala会自动进行类别指导
scala> val y:Int = 20 y: Int = 20 scala> val x = "asd" x: String = asd
2、函数与代码块
代码块(Block)
代码块用于组织多个表达式,代码块自身也是个表达式,求得的值是最后一个表达式的值。
代码块有两种写法:
1、表达式都写在一行,表达式之间分号分割
{exp1; exp2}
2、表达式分行,表达式末尾不需要分毫
{ exp1 exp2 }
函数
def functionName(param: paramType):returnType = { // function body: expressions }
示例代码如下:
object Hello { def helloDemo(name: String) = { s"Hello,${ name }" } def add(x:Int, y:Int): Int = { x+y } def main(arg: Array[String]) = { println(helloDemo("Yu Hang")) println(s"X + Y Result is ${add(12,34)}") } }
3、if、for表达式
在Scala里面,if和for并不是语句,而是一个表达式。 语句是可以单独执行的、能够产生实际效果的代码;而表达式则是包含在语句中,根据某种条件计算出一个值或得出某种结果,然后由语句去判断和处理的代码。
(1)if表达式
if(logical_exp) valA else valB
scala> if(true) 1 else 2 res44: Int = 1 scala> if(false) 3 else 4 res45: Int = 4 scala> val a = 1 a: Int = 1 scala> if(a == 1) a res46: AnyVal = 1 scala> if(a!= 1) a res47: AnyVal = () scala> if(a!=1) "not one" else a res48: Any = 1 scala> if(a!=1) "not one" res49: Any = ()
if(a!=1) a 的时候返回值是(), 因为“a!=1”是false,且 if 表达式没有 else,所以返回值为 空,Scala里面空是 Unit,所以if表达式的返回值就是Unit的文字量,就是一个空括号
(2)for comprehension
println("正常的for遍历:") for( s <- l) { // generator println(s) } println(" 带有 filter 的for遍历:") for( s <- l // generator if(s.length>4) // filter ) { println(s) } println(" 带有 filter 的for遍历:") val result_for = for{ s <- l // generator s1 = s.toUpperCase() // variable binding if(s1 != "") } yield (s1) // generator new collection for( item <- result_for ) println(item)
for 循环中的 yield 会把当前的元素记下来,保存在集合中,循环结束后将返回该集合。Scala 中 for 循环是有返回值的。如果被循环的是 Map,返回的就是 Map,被循环的是 List,返回的就是 List,以此类推。
4、try与match表达式
(1)try表达式
try {} catch {} finally {}
示例代码:
try { Integer.parseInt("dog") } catch { case _ => 0 } finally { println("always be printed") }
case _ => 0, "_"是通配符,无论try中是什么异常都会被catch到,并返回0。finally 是try{} catch{}之后执行的,无论表达式是否异常,都会执行finally。
(2)match与switch较为相似
exp match { case p1 => val1 case p2 => val2 ... case _ => valn }
其中的 "case _" 就相当于switch中的 default。
val code = 3 val result_match = code match { case 1 => println("one") case 2 => println("two") case 3 => println("three") case _ => println("other") }
5、求值策略
Scala中有两种求值策略(Evaluation Strategy)
1、 Call By Value - 对传入参数先进行求值,只一次求值
2、Call By Name - 函数实参每次在函数体内被调用到时都会进行求值
Scala 通常使用的时 Call By Value
如果函数形参类型以 “=>” 开头,则会使用 Call By Name
def foo( asd: Int) // Call By Value def foo( asd: => Int) // Call By Name
举个例子:下面定义了test1、test2. test1是Call By Value; text2是Call By Name.
def text1(x: Int, y: Int): Int = x*x def text2(x: => Int, y: => Int): Int = x*x
例 1 :
test1(3+4, 8) test1(7, 8) //test1 是Call By Value,首先会先算出参数 7*7 49 test2(3+4, 8) (3+4)*(3+4) // test2是 Call By Name, 直接把3+4传入test2,表达式替换x变量 7*(3+4) 7*7 49
例 2 :
test1(7, 2*4) test1(7, 8) //test1 是Call By Value,首先会先算出参数 2*4,再对x、y进行赋值 7*7 49 test2(7, 2*4) // test2是 Call By Name, 直接把2*4传入test2,表达式替换y变量 7*7 // 2*4 没用到,所以一直不需要进行计算 49