Scala学习笔记(五) - 控制语句

与其他的C类语言一样,Scala中也有一些常用的控制语句,与其他语言不一样的是,这些控制语句也产生返回值,听着很神奇?确实是

if 语句

与其他语言是一样的,判断一个条件是否为真,并执行其中的一条,例如:

val maxValue = if(x>y) x else y
同样也可以使用 ! 对操作结果取反(操作符将在下面一篇文章记述),例如:

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)
请注意第一个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 

其中,可以使用大括号代替小括号,好处是可以少写必须的;号

流间绑定:

个人认为这是很实用的一个功能,特别是在遍历树形结构时,非常的方便:

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")
}

这里使用了try-catch语句,与其他的语句的catch(Exception)不同的是,这里是用case e: XXX =>来进行处理的,同时可以继续返回值。

关于finally子句

finally子句与其他语言一样的,但是有一点需要注意的就是,finally中的返回值会覆盖try-catch中的返回值,所以在finally中不要返回任何值,只进行一些资源的释放就好了。

Scala中的基本控制语句就这些了,有点多?还是有点少?

好吧,估计你发现找不到了break 与 continue了吧,这两个关键字在scala中被移除了,因为他们不太符合函数式风格,根据作者的说法,如果充分利用函数字面量与递归可以很轻松的避开这两个关键字。


下面的一节会说一下Scala中的操作符以及一些其他我们在Java与C#中常用的东西。


你可能感兴趣的:(Scala)