1. 程式人生 > >scala高階特性

scala高階特性

2018-12-10 16:31:28

1.高階函式

1.1. 概念

Scala混合了面向物件和函數語言程式設計的特性,我們通常將可以做為引數傳遞到方法中的表示式叫做函式

1.2. 作為值的函式

可以像任何其他資料型別一樣被傳遞和操作的函式,每當你想要給演算法傳入具體動作時這個特性就會變得非常有用。

定義函式時格式:val 變數名 = (輸入引數型別和個數) => 函式實現和返回值型別和個數

“=”表示將函式賦給一個變數

“=>”左面表示輸入引數名稱、型別和個數,右邊表示函式的實現和返回值型別和引數個數

val arr = Array(1,2,3,4,5)
val fun1 = (x:Int) => x * 2 //定義一個函式並將函式賦給變數fun1
val res = arr.map(fun1)  //將函式作為引數傳入map方法中 

 

1.3. 匿名函式

Scala中,你不需要給每一個函式命名,沒有將函式賦給變數的函式叫做匿名函式

 

//直接將匿名函式傳入到map方法中,效果和前面一樣,比較精簡一些
val res = arr.map((x:Int) => x * 2)

 

由於scala可以自動推斷出引數的型別,所以可以寫的精簡一些

val res = arr.map(x => x * 2)
//神奇的下劃線
val res = arr.map(_*2)

  

1.4. 將方法轉換成函式

Scala中,方法和函式是不一樣的,最本質的區別是

函式可以做為引數傳遞到方法中

但是方法可以被轉換成函式,神奇的下劃線又出場了

 //定義一個方法
def m(x:Int) = x * 3
//神奇的下劃線將方法轉換成了函式
val fun2 = m _
//將函式傳入map方法中
val res = arr.map(fun2)

  

1.5. 柯里化

柯里化指的是將原來接收兩個引數列表的方法或函式變成新的一個引數列表的方法或函式的過程

//一個比較奇怪的方法,看起來即像方法又像函式
def m(x:Int) = (y:Int) => x * y
//將一個引數3傳進函式後,徹底變成了一個函式val func = (y:Int) => 3 * y
val func = m(3)
//然後在呼叫這個函式並傳遞第二個引數,得到最終結果
val res1 = func(5)

//簡寫為
def m(x:Int)(y:Int) = x * y 
val res = m(3)(5)

  

1.6. 例子

package com.qf.scala

object FunDemo {
  def main(args: Array[String]) {
    def f2(x: Int) = x * 2
    val f3 = (x: Int) => x * 3
    val f4: (Int) => Int = { x => x * 4 }
    val f4a: (Int) => Int = _ * 4
    val f5 = (_: Int) * 5
    val list = List(1, 2, 3, 4, 5)
    var new_list: List[Int] = null
    //第一種:最直觀的方式 (Int) => Int
    //new_list = list.map((x: Int) => x * 3)

    //第二種:由於map方法知道你會傳入一個型別為(Int) => Int的函式,你可以簡寫
    //new_list = list.map((x) => x * 3)

    //第三種:對於只有一個引數的函式,你可以省去引數外圍的()
    //new_list = list.map(x => x * 3)

    //第四種:(終極方式)如果引數在=>右側只出現一次,可以使用_
    new_list = list.map(_ * 3)

    new_list.foreach(println(_))

    var a = Array(1,2,3)
    a.map(_* 3)
  }
}

  

2. 隱式轉換和隱式引數

2.1. 概念

隱式轉換和隱式引數是Scala中兩個非常強大的功能,利用隱式轉換和隱式引數,你可以提供優雅的類庫,對類庫的使用者隱匿掉那些枯燥乏味的細節。

 

2.2. 作用

 

隱式的對類的方法進行增強,豐富現有類庫的功能

 

2.3. 隱式轉換函式

 

是指那種以implicit關鍵字宣告的帶有單個引數的函式

 

 

package com.qf.impli

import java.io.File
import scala.io.Source

//隱式的增強File類的方法
class RichFile(val from: File) {
  def read = Source.fromFile(from.getPath).mkString
}

object RichFile {
  //隱式轉換方法
  implicit def file2RichFile(from: File) = new RichFile(from)
}

object MainApp{
  def main(args: Array[String]): Unit = {
    //匯入隱式轉換
    import RichFile._
    //import RichFile.file2RichFile
    println(new File("c://words.txt").read)
  }
}

package com.qf.scala
import java.awt.GridLayout

object ImplicitContext{
  //implicit def girl2Ordered(g : Girl) = new Ordered[Girl]{
  //  override def compare(that: Girl): Int = if (g.faceValue > that.faceValue) 1 else -1
  //}

  implicit object OrderingGirl extends Ordering[Girl]{
    override def compare(x: Girl, y: Girl): Int = if (x.faceValue > y.faceValue) 1 else -1
  }
}

class Girl(var name: String, var faceValue: Double){
  override def toString: String = s"name : $name, faveValue : $faceValue"
}

//class MissRight[T <% Ordered[T]](f: T, s: T){
//  def choose() = if(f > s) f else s
//}
//class MissRight[T](f: T, s: T){
//  def choose()(implicit ord: T => Ordered[T]) = if (f > s) f else s
//}

class MissRight[T: Ordering](val f: T, val s: T){
  def choose()(implicit ord: Ordering[T]) = if(ord.gt(f, s)) f else s
}

object MissRight {
  def main(args: Array[String]) {
    import ImplicitContext.OrderingGirl
    val g1 = new Girl("yuihatano", 99)
    val g2 = new Girl("jzmb", 98)
    val mr = new MissRight(g1, g2)
    val result = mr.choose()
    println(result)
  }