与其他的C类语言一样,Scala中也有一些常用的控制语句,与其他语言不一样的是,这些控制语句也产生返回值,听着很神奇?确实是
if 语句
与其他语言是一样的,判断一个条件是否为真,并执行其中的一条,例如:
[java]
- val maxValue = if(x>y) x else y
同样也可以使用 ! 对操作结果取反(操作符将在下面一篇文章记述),例如:
[java]
- val maxValue = if(!(x>y)) x else y
match语句
该语句与其他语言中的switch有点像,确切的说与C#的switch更为接近,因为它可以对任意值进行匹配,java中只能对数字和枚举进行匹配。
同时该语句也可以返回值,这点很爽,
例如:
[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语句
这个与其他语句的基本一样,稍微不一样的就是它也可以把值返回给一个字段或者其他什么对象,例如:
[java]
- var a = 0;
- while(a <100)
- {
- a = a + 1
- }
- // 或
- do
- {
- a = a+1
- }
- while(a<100)
需要注意的是,在Scala中,赋值语句永远都返回unit值,所以在其他语句中常用的一些方法可能不再适用于Scala例如:
[java]
- var line = ""
- while((line = readLine()) != "")
- {
- //
- }
这时,你会收到编译器编译警告,Unit与String对比将永远返回true
for语句
Scala中的For语句比较复杂,与其他的语言for语句来说,多了很多扩展的东西,一步一步来吧
最简单的:
[java]
- val files = someArray
- for(file <- files)
- println(file)
这里使用 <-作为遍历语句,个人感觉这个符号很难打
如果用数字循环的话,可以使用to或until函数,例如:
[java]
- for(i <- 0 to 100)
- println("I: " + i) // 输出到100
- for(i <- 0 until 100) // 输出到99
- println("I:" + i)
使用过滤条件:
Scala可以在循环的时候增加过滤条件,例如:
[java]
- for(i <- 0 to 100 if (i % 2) == 1 )
- println("I: " + i)
也可以使用多个if语句进行多层过滤,例如:
[java]
- for(i <- 0 to 100
- if (i % 2) == 1;
- if (i % 5) > 3 )
- println("I: " + i)
请注意第一个if语句后面的;号,scala规定,多个过滤器的时候,必须使用;号进行分隔
嵌套枚举:
与普通的for嵌套的区别在于,你可以少写 "for" 这三个字母 其他的基本一样,例如:
[java]
- 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.*")
其中,可以使用大括号代替小括号,好处是可以少写必须的;号
流间绑定:
个人认为这是很实用的一个功能,特别是在遍历树形结构时,非常的方便:
[java]
- 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循环体外面,例如:
[java]
- 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中依然会返回值,例如:
[java]
- val half =
- if (n % 2 == 0)
- n / 2
- else
- throw new RuntimeException("n must be even")
如果抛出了异常,half其实也依然有值,看上去很神奇,但有时却很有用。
[java]
- 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中被移除了,因为他们不太符合函数式风格,根据作者的说法,如果充分利用函数字面量与递归可以很轻松的避开这两个关键字。
下面的一节会说一下Scala中的操作符以及一些其他我们在Java与C#中常用的东西。