【Scala篇】--Scala中的函式

LHBlog發表於2018-02-01

一、前述

Scala中的函式還是比較重要的,所以本文章把Scala中可能用到的函式列舉如下,並做詳細說明。

二、具體函式

1、Scala函式的定義

def fun (a: Int , b: Int ) : Unit = {
   println(a+b)
 }
fun(1,1)
    
def fun1 (a : Int , b : Int)= a+b
    println(fun1(1,2))  

 

注意點:

函式定義語法 def來定義

l可以定義傳入的引數,要指定傳入引數的型別

方法可以寫返回值的型別也可以不寫,會自動推斷,有時候不能省略,必須寫,比如在遞迴函式中或者函式的返回值是函式型別的時候。

 scala中函式有返回值時,可以寫return,也可以不寫return會把函式中最後一行當做結果返回。當寫return時,必須要寫函式的返回值。

如果返回值可以一行搞定,可以將{}省略不寫

傳遞給方法的引數可以在方法中使用,並且scala規定方法的傳過來的引數為val的,不是var的。

如果去掉方法體前面的等號,那麼這個方法返回型別必定是Unit的。這種說法無論方法體裡面什麼邏輯都成立,scala可以把任意型別轉換為Unit.假設,裡面的邏輯最後返回了一個string,那麼這個返回值會被轉換成Unit,並且值會被丟棄。

 

2、遞迴函式

 

  /**
     * 遞迴函式 
     * 5的階乘
     */
    def fun2(num :Int) :Int= {
      if(num ==1)
        num
      else 
        num * fun2(num-1)
    }
    print(fun2(5))

 

 3、包含引數預設值的函式

       預設值的函式中,如果傳入的引數個數與函式定義相同,則傳入的數值會覆蓋預設值

 

       如果不想覆蓋預設值,傳入的引數個數小於定義的函式的引數,則需要指定引數名稱

 

**
     * 包含預設引數值的函式
     * 注意:
     * 1.預設值的函式中,如果傳入的引數個數與函式定義相同,則傳入的數值會覆蓋預設值
     * 2.如果不想覆蓋預設值,傳入的引數個數小於定義的函式的引數,則需要指定引數名稱
     */
    def fun3(a :Int = 10,b:Int) = {
      println(a+b)
    }
    fun3(b=2)

 

 4、可變引數個數的函式

            多個引數用逗號分開

 

   /**
     * 可變引數個數的函式
     * 注意:多個引數逗號分開
     */
    def fun4(elements :Int*)={
      var sum = 0;
      for(elem <- elements){
        sum += elem
      }
      sum
    }
    println(fun4(1,2,3,4))

 

 

5、匿名函式

有參匿名函式

無參匿名函式

有返回值的匿名函式

可以將匿名函式返回給val定義的值

匿名函式不能顯式宣告函式的返回型別

 

/**
     * 匿名函式
     * 1.有引數匿名函式
     * 2.無引數匿名函式
     * 3.有返回值的匿名函式
     * 注意:
     * 可以將匿名函式返回給定義的一個變數
     */
    //有引數匿名函式
    val value1 = (a : Int) => {
      println(a)
    }
    value1(1)
    //無引數匿名函式
    val value2 = ()=>{
      println("我愛。。。")
    }
    value2()
    //有返回值的匿名函式
    val value3 = (a:Int,b:Int) =>{
      a+b
    }
    println(value3(4,4)) 

6、巢狀函式

 

/**
     * 巢狀函式
     * 例如:巢狀函式求5的階乘
     */
    def fun5(num:Int)={
      def fun6(a:Int,b:Int):Int={
        if(a == 1){
          b
        }else{
          fun6(a-1,a*b)
        }
      }
      fun6(num,1)
    }
    println(fun5(5))

 

 7、偏應用函式

偏應用函式是一種表示式,不需要提供函式需要的所有引數,只需要提供部分,或不提供所需引數。

 

    /**
     * 偏應用函式
     */
    def log(date :Date, s :String)= {
      println("date is "+ date +",log is "+ s)
    }
    
    val date = new Date()
    log(date ,"log1")
    log(date ,"log2")
    log(date ,"log3")
    
    //想要呼叫log,以上變化的是第二個引數,可以用偏應用函式處理
    val logWithDate = log(date,_:String)
    logWithDate("log11")
    logWithDate("log22")
    logWithDate("log33")

 

 8、高階函式

 

函式的引數是函式,或者函式的返回型別是函式,或者函式的引數和函式的返回型別是函式的函式。

 

     函式的引數是函式

 

     函式的返回是函式

 

     函式的引數和函式的返回是函式

 

/**
     * 高階函式
     * 函式的引數是函式		或者函式的返回是函式		或者函式的引數和返回都是函式
     */
    
    //函式的引數是函式
    def hightFun(f : (Int,Int) =>Int, a:Int ) : Int = {
      f(a,100)
    }
    def f(v1 :Int,v2: Int):Int  = {
      v1+v2
    }
    
    println(hightFun(f, 1))
    
    //函式的返回是函式
    //1,2,3,4相加
    def hightFun2(a : Int,b:Int) : (Int,Int)=>Int = {
      def f2 (v1: Int,v2:Int) :Int = {
        v1+v2+a+b
      }
      f2
    }
    println(hightFun2(1,2)(3,4))
    
    //函式的引數是函式,函式的返回是函式  因為函式的返回是函式,所以可以理解為呼叫hightFunc2(1,2)的返回是函式,所以需要在傳進去一個引數。
    def hightFun3(f : (Int ,Int) => Int) : (Int,Int) => Int = {
      f
    } 
    println(hightFun3(f)(100,200))
    println(hightFun3((a,b) =>{a+b})(200,200))
    //以上這句話還可以寫成這樣
    //如果函式的引數在方法體中只使用了一次 那麼可以寫成_表示
    println(hightFun3(_+_)(200,200))

 

 

9、柯里化函式

  可以理解為高階函式的簡化

  /**
     * 柯里化函式
     */
    def fun7(a :Int,b:Int)(c:Int,d:Int) = {
      a+b+c+d
    }
    println(fun7(1,2)(3,4))

 

 

 

 

 

 

 

 

 

 

 

 

 

相關文章