1 :条件表达式
Scala中if/else 语法结构和java,C 一样,不过,在Scala中if/else表达式有值,这个值就是跟在if或者else之后的表达式的值,例如:
if(x >0 ) 1 else -1
那么我们可以这样来写
val s = if(x >0 ) 1 else -1
这个表达式是有值得,最终的值就是1或者-1 ,以上的写法在java中就是
if(x > 0) s = 1 else s = -1
明显的第一种写法会更好一些,因为它可以用来初始化一个val,而在第二种写法中,变量必须是var的
在Java中,有一个三元表达式比如:int i = n > 0 ? 1 : 0
那么这个在scala中就是val s = if(x >0 ) 1 else -1
在Scala中,每个表达式都有一个类型,比如上面你的表达式返回类型是int类型,因为两个分支都是int类型的,但是如果两个分支的类型不同,那么最终返回的就是Scala中的超类Any,Any在Scala中是所有类型的超类
val res = if(n > 0) "result" else 1
比如上面的一条语句,返回的类型就是Any的
2 : 循环
在scala中,while循环和在java与C 中一样
代码语言:javascript复制while(n > 0){
n -= 1
}
在scala中没有与for循环直接对应的结构,如果需要这样的循环我们可以使用while或者使用scala版的for
代码语言:javascript复制for( i <- 1 to n ){
println(i)
}
1 to n 指的是循环1到n个元素索引。
表达式结构:for(i <- 表达式)
让变量i遍历<- 右边的表达式的所有值
在遍历字符串或者数组时,通常需要使用0 到 n-1的区间,这个时候可以用 util方法而不是to,util方法会犯一个并不包含上限的区间
代码语言:javascript复制val s = "hello"
var sum = 0
for(i <- i util s.length) sum = s(i)
或者我们并不需要下标
代码语言:javascript复制var sum = 0
for( i <- "hello" ) sum = i
Scala中并没有提供break或者continue语句来退出循环,那么囚需要break时,该如何做呢
1.使用Boolean类型来控制变量
2:使用嵌套函数-在函数当中return
3:使用Breaks对象中的break方法
代码语言:javascript复制breakable{
for( ... ){
if(...) break
}
}
3 : 高级for循环和for推导式
在上面循环中我们只看到了基本的for循环,在scala中for循环比起java和c 功能要丰富很多。下面来看一看for循环的高级特性
可以以变量<-表达式的形式提供多个生成器,用分号将它们隔开
代码语言:javascript复制for( i <- 1 to 3 ; j <- 1 to 3 ) println((i j) " ")
每个生成器都带一个守卫,以if开头的Boolean表达式
代码语言:javascript复制for( i <- 1 to 3; j<-1 to 3 if i != j ) println((i j) " ")
注意:在if之前并没有分号
也可以使用任意多的定义,引入可以在循环中使用的变量
代码语言:javascript复制for( i <- 1 to 3 ; from = 4 - i ; j <- from to 3 ) println(i j)
如果for循环的循环体以yield开始,则该循环会构造出一个集合,每次迭代生成集合中的一个值,比如:
代码语言:javascript复制for(i <- 1 to 10) yield i % 3
// 生成 Vector(1,2,0,1,2,0,1,2,0,1)
这类循环叫做for推导式
假如你并不需要打印过滤后的集合,你需要编写代码对过滤后的集合进行处理,那么该怎
么办呢?使用 yield 关键字便能在 for 表达式中生成新的集合。比如:
代码语言:javascript复制val dogBreeds = List("Doberman", "Yorkshire Terrier", "Dachshund",
"Scottish Terrier", "Great Dane", "Portuguese Water Dog")
val filteredBreeds = for {
breed <- dogBreeds
if breed.contains("Terrier") && !breed.startsWith("Yorkshire")
} yield breed
每次执行 for 表达式时,过滤后的结果将生成 breed 值。随着代码的执行,这些结果
值逐渐积累起来,累计而成的结果值集合被赋给了 filteredBreeds 对象。 for-yield
表达式所生成的集合类型将根据被遍历的集合类型推导而出。在上面的例子中,由
于 filteredBreeds 源 于 dogBreeds 列 表, 而 dogBreeds 类 型 为 List[String], 因 此
filteredBreeds 的类型为 List[String]。
for 推导式有一个不成文的约定:当 for 推导式仅包含单一表达式时使用原
括号,当其包含多个表达式时使用大括号。值得注意的是,使用原括号时,
早前版本的 Scala 要求表达式之间必须使用分号。
4 : 懒值(lazy)
当val被声明为lazy时,那么该变量的初始化将被推迟,直到我们首次对它取值。例如
lazy val words = scala.io.Source.fromFile("/usr/local/dic/words").mkString
上面我们定义了一个lazy 的words,如果我们在后面的程序中一直没有调用words,那么这个word就一直不会执行,一直到我们去调用它才会去执行文件的读取操作。
由于表达式执行代价昂贵(例如: 打开一个数据库连接), 因此我们希望能推迟该操作,
直到我们确实需要表达式结果值时才执行它。
• 为了缩短模块的启动时间,可以将当前不需要的某些工作推迟执行。
• 为了确保对象中其他的字段的初始化过程能优先执行,需要将某些字段惰性化
那么惰性赋值与方法调用有那些差别呢?对于方法调用而言,每次调用方法时方法体都会
被执行;而惰性赋值则不然,首次使用该值时,用于初始化的“代码体”才会被执行一
次。这种只能执行一次的计算对于可变字段而言几乎没有任何意义。因此, lazy 关键字并
不能用于修饰 var 变量。