与其他的C类语言一样,Scala中也有一些常用的控制语句,与其他语言不一样的是,这些控制语句也产生返回值,听着很神奇?确实是
if 语句
与其他语言是一样的,判断一个条件是否为真,并执行其中的一条,例如:
val maxValue = if(x>y) x else y
match语句
该语句与其他语言中的switch有点像,确切的说与C#的switch更为接近,因为它可以对任意值进行匹配,java中只能对数字和枚举进行匹配。
同时该语句也可以返回值,这点很爽,
例如:
val sample = xxx // 随便一个什么字符串
val friend =
sample match{
case "A" => "a"
case "B" => "b"
case _ => "nothing"
}
其中 sample是你要用来对比的表达式或者其他随便什么东西,类似于switch语句中 switch(sample)的东西
然后 case 后面不在使用 : 而是使用 =>
然后 case 之间没有了 break,这是因为Scala不允许从一个case跳转到另一个case,如果需要跳转怎么办?我也不知道 了不过我回先记下,问问老师去,呵呵。
然后 没有了default 取而代之的是 _ ,在Scala中_ 是一个很神奇的存在,貌似到处都能看到他的身影,总而言之 _ 代替了default存在。
最后,发现整个match的匹配结果赋值给了friend不变量,是的,这很好用对吧。
while / do while语句
这个与其他语句的基本一样,稍微不一样的就是它也可以把值返回给一个字段或者其他什么对象,例如:
var a = 0;
while(a <100)
{
a = a + 1
}
// 或
do
{
a = a+1
}
while(a<100)
需要注意的是,在Scala中,赋值语句永远都返回unit值,所以在其他语句中常用的一些方法可能不再适用于Scala例如:
var line = ""
while((line = readLine()) != "")
{
//
}
这时,你会收到编译器编译警告,Unit与String对比将永远返回true
for语句
Scala中的For语句比较复杂,与其他的语言for语句来说,多了很多扩展的东西,一步一步来吧
最简单的:
val files = someArray
for(file <- files)
println(file)
这里使用 <-作为遍历语句,个人感觉这个符号很难打
如果用数字循环的话,可以使用to或until函数,例如:
for(i <- 0 to 100)
println("I: " + i) // 输出到100
for(i <- 0 until 100) // 输出到99
println("I:" + i)
使用过滤条件:
Scala可以在循环的时候增加过滤条件,例如:
for(i <- 0 to 100 if (i % 2) == 1 )
println("I: " + i)
也可以使用多个if语句进行多层过滤,例
for(i <- 0 to 100
if (i % 2) == 1;
if (i % 5) > 3 )
println("I: " + i)
for(i <- 0 to 100
if (i % 2) == 1;
if (i % 5) > 3 )
println("I: " + i)
请注意第一个if语句后面的;号,scala规定,多个过滤器的时候,必须使用;号进行分隔
嵌套枚举:
与普通的for嵌套的区别在于,你可以少写 "for" 这三个字母 其他的基本一样,例如:
def fileLines(file: java.io.File) =
scala.io.Source.fromFile(file).getLines.toList
def grep(pattern: String) =
for (
file <-filesHere
if file.getName.endsWith(".scala");
line <fileLines(file)
if line.trim.matches(pattern)
) println(file +": "+ line.trim)
grep(".*gcd.*")
其中,可以使用大括号代替小括号,好处是可以少写必须的;号
流间绑定:
个人认为这是很实用的一个功能,特别是在遍历树形结构时,非常的方便:
def grep(pattern: String) =
for {
file <- filesHere
if file.getName.endsWith(".scala")
line <- fileLines(file)
trimmed = line.trim
if trimmed.matches(pattern)
} println(file +": "+ trimmed)
grep(".*gcd.*")
这里在for语句中定义了一个变量 trimmed并对其赋值,注意,for使用的是大括号
创造新集合:
这里在for循环后面使用yield关键字来创建新的集合,类似于:
for { } yield {} 其中yield位于for循环体外面,例如:
val forLineLengths =
for {
file <- filesHere
if file.getName.endsWith(".scala")
line <- fileLines(file)
trimmed = line.trim
if trimmed.matches(".*for.*")
} yield trimmed.length
这里遍历了所有文件,并根据文件名为.scala的文件取出所有的行,并去空格,然后匹配 ".*for.*"之后,取长度创建一个新数组(有人能看明白?哈哈)
嗯,总之很简单的可以创建很多东西,这里有点类似于C#的linq的用法
上面只是基本的for语句用法,至于后面还有什么,我也还没看到,哈哈
try-catch-finlly 、throw语句
与其他语言的用法相似,只是Scala中依然会返回值,例如:
val half =
if (n % 2 == 0)
n / 2
else
throw new RuntimeException("n must be even")
如果抛出了异常,half其实也依然有值,看上去很神奇,但有时却很有用
import java.net.URL
import java.net.MalformedURLException
def urlFor(path: String) =
try {
new URL(path)
} catch {
case e: MalformedURLException =>
new URL("http://www.scalalang.org")
}
import java.net.URL
import java.net.MalformedURLException
def urlFor(path: String) =
try {
new URL(path)
} catch {
case e: MalformedURLException =>
new URL("http://www.scalalang.org")
}
这里使用了try-catch语句,与其他的语句的catch(Exception)不同的是,这里是用case e: XXX =>来进行处理的,同时可以继续返回值。
关于finally子句
finally子句与其他语言一样的,但是有一点需要注意的就是,finally中的返回值会覆盖try-catch中的返回值,所以在finally中不要返回任何值,只进行一些资源的释放就好了。
Scala中的基本控制语句就这些了,有点多?还是有点少?
好吧,估计你发现找不到了break 与 continue了吧,这两个关键字在scala中被移除了,因为他们不太符合函数式风格,根据作者的说法,如果充分利用函数字面量与递归可以很轻松的避开这两个关键字。
ok 先总结到这以后在学到在加就是了