1. 程式人生 > >Scala之柯里化和隱式轉換

Scala之柯里化和隱式轉換

1. 柯里化

柯里化指將原來接受兩個引數的函式變成一個新的接受一個引數的過程。新的函式返回一個以原有第二個引數作為引數的函式。

scala> val mul = (x: Int, y: Int) => x*y
mul: (Int, Int) => Int = <function2>

scala> val mulOneAtTime = (x: Int) => ((y: Int) => x*y) // 柯里化
mulOneAtTime: Int => (Int => Int) = <function1>

scala> mulOneAtTime(6)(7)
res0: Int = 42

scala> def mulOneTimel(x: Int)(y: Int) = x*y // 簡寫的柯里化
mulOneTimel: (x: Int)(y: Int)Int

scala> mulOneTimel(6)(7)
res1: Int = 42

2. 隱式轉換和隱式引數

2.1. 概念

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

2.2. 作用

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

2.3. 隱式轉換函式

是指那種以 implicit 關鍵字宣告的帶有單個引數的函式,這種函式將被自動引用,將值從一種型別轉換成另一種型別。

2.4. 案例

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 ImplicitTransferDemo{
  def main(args: Array[String]): Unit = {
    //匯入隱式轉換
    import RichFile._
    //import RichFile.file2RichFile
    println(new File("c://words.txt").read)

  }
}

注意:

(1) 只能在別的trait/類/物件內部定義。

object Helpers {
       implicit class RichInt(x: Int) // 正確!
    }
    implicit class RichDouble(x: Double) // 錯誤!

(2) 建構函式只能攜帶一個非隱式引數。

 implicit class RichDate(date: java.util.Date) // 正確!
 implicit class Indexer[T](collecton: Seq[T], index: Int) // 錯誤!
 implicit class Indexer[T](collecton: Seq[T])(implicit index: Index) // 正確!

雖然我們可以建立帶有多個非隱式引數的隱式類,但這些類無法用於隱式轉換。

(3) 在同一作用域內,不能有任何方法、成員或物件與隱式類同名。這意味著隱式類不能是case class。

object Bar
implicit class Bar(x: Int) // 錯誤!

val x = 5
implicit class x(y: Int) // 錯誤!

implicit case class Baz(x: Int) // 錯誤!