scala之函数

  Scala除了方法,还支持函数。例如String就有很多方法,这些方法都是对String对象进行操作,但是函数不是。

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

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

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


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

        

[java]  view plain  copy
  1. def sum(n:Int) = {  
  2.   
  3.       for (i <- 1 to 10)   
  4.             r = r*i  
  5.             r  
  6.  }   

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

         

[java]  view plain  copy
  1. def sum(n:Int):Int = {  
  2.   
  3.       for (i <- 1 to 10)   
  4.             r = r*i  
  5.            return r  
  6.  }    

          其与上面的是一样的,只是上面的写法更简洁。


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

   

[java]  view plain  copy
  1. def fac(n:Int):Int = if( n <= 01 else n*fac(n-1)  
  2.   
  3. println(fac(5)) //120  
   

默认参数和代码参数:

     

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

         

[java]  view plain  copy
  1. def outputBookName(bookname:String,left:String="{",right:String="}") =  
  2.   left + bookname + right  
  3.   
  4. println(outputBookName("book1"))  
  5.   
  6. println(outputBookName("book2""[""]"))  
  7.   
  8. println(outputBookName(right="***]",bookname="book3"))  
 输出:

       {book1}   --》使用了默认参数
        [book2]    --》 使用了传入的参数
        {book3***] --》根据需要,提供参数名称和值替换默认值


变长参数:

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

    

[java]  view plain  copy
  1. def sum1(args : Int*) = {  
  2.      var result = 0  
  3.      for(arg <- args)  
  4.         result += arg  
  5.         result  
  6.    }  
  7.      
  8.    println(sum1(5,4,3,2,1)) //15  
 

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

 

[java]  view plain  copy
  1. val s = sum1(1 to 5: _*)  //将1到5当做参数序列处理  

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

 

[java]  view plain  copy
  1. def sum2(args : Int*):Int = {  
  2.       if(args.length == 0 )  
  3.         0  
  4.       else  
  5.         args.head + sum2(args.tail: _*)  
  6.    }  
  7.      
 序列的head是参数args的首个元素,而tail是所有其它的元素序列,这是个Seq,需要用 _*将它转为参数序列。



过程:

   定义:

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

过程不返回值,我们调用它是为了使用它的副作用。如:我们需要打印一些图案,那么可以定义一个过程:

 

[java]  view plain  copy
  1.     def draw(s:String) {  
  2.         
  3.       println("-------")  
  4.       println("|"+"   "+"|")  
  5.       println("|"+s+"|")  
  6.       println("|"+"   "+"|")  
  7.       println("-------")  
  8.     }  
  9.       
  10.     println(draw("123"));  
  11.   
  12. 输出:  
  13.   
  14. -------  
  15. |   |  
  16. |123|  
  17. |   |  
  18. -------  
  19. ()  

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


懒值:

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

    

[java]  view plain  copy
  1. lazy val file1 = scala.io.Source.fromFile("C:/hello.scala").mkString  
  2.   
  3. println(file1)   
输出:

println("hello")


如果我们不调用

[java]  view plain  copy
  1. println(file1)   

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

    

异常:


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

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

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


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


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




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


[java]  view plain  copy
  1. var in = new URL("http://ubmcmm.baidustatic.com/media/v1/0f0000g0bymVB3uhUffi-0.gif").openStream();  
  2.      
  3.    try {  
  4.      process(in)  
  5.    }finally {  
  6.      in.close()  
  7.    }  
  8.      
  9.    def process(in:java.io.InputStream) = {  
  10.        
  11.      println(in.toString());  
  12.        
  13.    }  

输出:sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@8b33e8
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值