天天看點

Scala的高階函數使用總結

    函數在Scala語言中有着舉足輕重的地位,它和類,變量同樣屬于一等公民的地位,函數可以脫離類而獨立存在,同時自己也可以作為參數傳遞給其他函數。

    匿名函數

scala> val sayHello = (name: String) => println("my name is:" + name)
sayHello: String => Unit = <function1>

scala> sayHello("cyony")
my name is:cyony
           

    sayHello變量就是一個函數,它沒有自己的函數名,隻定義了函數簽名,以及函數體,傳回類型為Unit,可以看到編譯器自動為這個匿名函數取名為function1。在實際調用時,直接調用這個函數變量,傳入一個String類型的值,即可。

    無傳回高階函數

scala> val sayHello = (name: String) => println("my name is:" + name)
sayHello: String => Unit = <function1>

scala> sayHello("cyony")
my name is:cyony

scala>   def introduce(fun: (String) => Unit, name: String, age: Int): Unit = {
     |     println("my age is:"+age)
     |     fun(name)
     |   }
introduce: (fun: String => Unit, name: String, age: Int)Unit

scala> introduce(sayHello,"cyony",25)
my age is:25
my name is:cyony
           

    上面一步定義了匿名函數,且指派給了sayHello變量。然後定義了一個introduce函數,他的簽名為,第一參數為一個方法,此fun的簽名為一個String變量,傳回類型是Unit;第二個參數是一個String類型的變量;第三個參數是Int類型的變量。因為fun變量自己就是一個函數,且又傳給了introduce函數,是以稱fun為他的高階函數。在調用的時候,為fun傳入sayHello變量,最終列印結果如上所示。

    有傳回高階函數

scala> def introduce(age: Int) = (name: String) => println("my name is:" + name + ",my age is:" + age)
introduce: (age: Int)String => Unit

scala>  val introduceFun = introduce(25)
introduceFun: String => Unit = <function1>

scala> introduceFun("cyony")
my name is:cyony,my age is:25
           

    這個例子和上面的相比,有點不同,introduce函數本身傳回的也是一個函數,可以看到repl的提示,傳回一個簽名為String,傳回為Unit的匿名函數,函數主體則是列印那句話。在調用的時候,首先得到這個匿名函數,然後再調用這個匿名函數。這個匿名函數同樣是introduce的高階函數。

    Currying函數

scala> def introduce(age: Int)(name: String) = println("my name is:" + name + ",my age is:" + age)
introduce: (age: Int)(name: String)Unit

scala> introduce(25)("cyony")
my name is:cyony,my age is:25
           

    函數的currying化行為本質上也是一個高階函數:接受現有的函數,傳回新函數。 這個例子就是對上一個例子的currying化操作。傳入第一個參數後傳回一個函數,然後再傳入第二個參數,完成第二個函數。這樣就講一個高階函數拆解成兩個一階函數。

    高階函數類型推斷

scala>   def triple(fun: (Int) => Int, num: Int) = {
     |     fun(num)
     |   }
triple: (fun: Int => Int, num: Int)Int

scala> triple(_*3,5)
res12: Int = 15
           

    如上所示,定義了一個triple函數,他的簽名是一個高階函數和一個整形。在這個函數實際使用的時候,用了占位符來替換傳入參數,因為傳入的參數肯定是Int類型,且在此主體中隻使用了一次,是以可以直接用占位符表示,省去了函數簽名以及傳回,直接定義主體,使得文法非常精簡。

繼續閱讀