Scala入门系列

Posted 大数据之心

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Scala入门系列相关的知识,希望对你有一定的参考价值。


基本控制结构即函数定义

1、if----else

If else都有返回值的,每一个函数体最后一句就是返回值。如下:

如果函数体不是一行语句,则加“{}”:如下

Scala入门系列(2)


当然也可以进入:paste模式

赋值

a=b=6;该语句会报错,如下:

Scala入门系列(2)



由错误可知“b=6”这条语句返回值是Unit,不能赋值给a;

由于初学,我们认为Unit是Scala的一个“没有用的占位符”,和Java的Void一样,但是Void没有占位。

输入输出

输入

导入import scala.io

其中scala.io.StdIn.readLine()可以读入控制台的信息,当然还有很多和Java类似的readInt、readDouble等Scan方法。

如下:


Scala入门系列(2)


输入my name is leo。如下

Scala入门系列(2)



输出

print;具体操作如下图所示:

Scala入门系列(2)

Scala入门系列(2)


其中,s,f,raw都是前缀,s为字符串包含表达式,但没有格式化指令;raw里可以定义转义字符;f,可以捕获编译错误;

“$”为引入变量的打头字母,相当于标识符;$name代表name的值

循环

While 、、、for、、实例如下:

和Java类似,不在赘述

但是没有break语句,一般用return或者flag来结束循环。或者引入breakable,如下:

Scala入门系列(2)



高级for循环和for推导式

Scala中的for循环比起Java和C++功能要丰富的多。

1、可以以变量<-表达式的形式提供多个生成器,用分号将它们隔开。如:

[java] view plain copy

for(i <- 1 to 3; j <- 1 to 3) {  

 print((10 * i + j) + " ");  

}  

 

tputs: 11 12 13 21 22 23 31 32 33  

2、每个生成器都可以带一个守卫,以if开头的Boolean表达式:

[java] view plain copy

for(i <- 1 to 3; j <- 1 to 3 <span style="color:#ff0000;">if i != j</span>) {  

   print((10 * i + j) + " ");  

 }  

 

outputs: 12 13 21 23 31 32  

注意在if之前并没有分号。

3、可以使用任意多的定义,引入可以在循环中使用的变量:

[java] view plain copy

for(i <- 1 to 3; from = 4 - i; j <- from to 3) {  

   print((10 * i + j) + " ");  

 }  

 

outputs: 13 22 23 31 32 33  

4、如果for循环的循环体以yield开始,则该循环会构造出一个集合,每次迭代生成集合中的一个值:

[java] view plain copy

<span style="font-size:18px;">for(i <- 1 to 10) yield {  

     var r = i % 3  

     print(r + " ")  

 }  

 

//生成 Vector(1, 2, 0, 1, 2, 0, 1, 2, 0, 1)  

outputs: 1 2 0 1 2 0 1 2 0 1</span>  

这类循环叫做for推导式。

for推导式生成的集合与它的第一个生成器是类型兼容的。

[java] view plain copy

for (c <- "Hello"; i <- 0 to 1) yield {  

   var v = (c + i).toChar;  

   print(v);  

 }  

 

outputs: HIeflmlmop  

说明:如果你愿意,你也可以将生成器、守卫和定义包含在花括号中,并可以以换行的方式而不是分号来隔开它们:

[java] view plain copy

for{i <- 1 to 3  

     from = 4 - i  

     j <- from to 3  

   }  

 print((10 * i + j) + " ")  

 

outputs: 13 22 23 31 32 33  

函数与过程

Scala除了方法,还支持函数。方法对对象进行操作,函数不是。

定义函数,需要给出函数的名称、参数和函数体。如:

def sum(x:int) = if(x>=0) x else -x

函数需要给出所有参数的类型。只要函数不递归,就不需要知道返回列下。Scala可以根据=号右侧表达式推导出放回类型。

如果函数体需要多个表达式完成,可以使用代码块。块的最后一个表达式的值就是函数的返回值。如:

       

def sum(n:Int) = {  

 

     for (i <- 1 to 10)  

           r = r*i  

           r  

}  

此函数r即是函数的返回值。如果使用return返回r的值,那么需要明确指定函数返回类型,如下所示:

def sum(n:Int):Int = {  

 

     for (i <- 1 to 10)  

           r = r*i  

          return r  

}    

如果是递归函数,必须需要指定返回类型。如:

 

def fac(n:Int):Int = if( n <= 0) 1 else n*fac(n-1)  

 

println(fac(5)) //120  

 

默认参数和代码参数:

   

有些情况下我们不需要给出全部参数,对应这类函数我们可以使用默认参数,当然你需要知道参数顺序或者参数名称。如:

       

def BookName(bookname:String,left:String="{",right:String="}") =  

 left + bookname + right  

 

println(outputBookName("book"))  

 

println(outputBookName("book", "[", "]"))  

 

println(outputBookName(right="***]",bookname="book"))  

输出:

      {book}   -

       [book]    

       {book***]

变长参数:

     实现一个可以接受可变长度的参数列表的函数,如:

   

def sum (args : Int*) = {  

    var result = 0  

    for(arg <- args)  

       result += arg  

       result  

  }  

   

  println(sum (5,4,3,2,1))

实现一个序列作为参数传入上述函数中,需要追加 _*,告诉编译器希望把这个参数当做序列处理。如:

val s = sum1(1 to 5: _*)  //将1到5当做参数序列处理  

在递归中我们同样可以使用这种方式,如:

def sum(args : Int*):Int = {  

     if(args.length == 0 )  

       0  

     else  

       args.head + sum(args.tail: _*)  

  }  

   

序列的head是参数args的首个元素,而tail是所有其它的元素序列,这是个Seq,需要用 _*将它转为参数序列。

过程:

   Scala对不返回值的函数有特殊的表示法。如果函数体包含在花括号中但没有前面的=号,那么返回类型是Unit。这样的函数叫做过程。过程不返回值,我们调用它是为了使用它的副作用。


看上面的返回,可以明显的指定这个函数的返回值是Unit;

懒值:

当val被声明为lazy时,它的初始化将被推迟,知道我们首次取它的值。如:

   

lazy val file1 = scala.io.Source.fromFile("C:/hello.scala").mkString  

 

println(file1)  

输出:

println("hello")

如果我们不调用

println(file1)  

 这行语句,即file1不被访问,那么文件就不会被打开。

   

异常:

Scala异常的工作机制同Java。当你需要抛出异常时,如:

  throw new FileNotFoundException("系统找不到指定的文件。")

Scala异常同Java一样,抛出的异常必须是java.lang.Throwable的子类。其与Java不同的是,Scala没有受检异常,不需要声明函数或者方法可能会抛出异常。

throw 表达式有特殊类型Nothing。这在if else表达式中很有用。如果一个分支的类型是Nothing,那么if else表达式的类型就是另外一个分支的类型。

捕获异常的语法采用模式匹配的语法。如:

try finally语句可以释放资源,不论是否发生异常。如:

var in = new URL("http://ubmcmm.baidustatic.com/media/v1/0f0000g0bymVB3uhUffi-0.gif").openStream();  

   

  try {  

    process(in)  

  }finally {  

    in.close()  

  }  

   

  def process(in:java.io.InputStream) = {  

     

    println(in.toString());  

     

  }  

输出:sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@8b33e8

预习部分:









以上是关于Scala入门系列的主要内容,如果未能解决你的问题,请参考以下文章

Scala入门系列:函数式编程

Scala入门系列:函数式编程之集合操作

scala入门系列--数组

Scala入门系列

Scala入门系列:面向对象之继承

Scala入门系列:面向对象之trait