1. 程式人生 > >scala的apply和unapply方法

scala的apply和unapply方法

當scala中類或者物件有一個主要用途的時候,apply方法就是一個很好地語法糖。

請看下面一個簡單的例子:

class Foo(foo: String) {
}

object Foo {
    def apply(foo: String) : Foo = {
        new Foo(foo)
    }
}

定義了一個Foo類,並且在這個類中,有一個伴生物件Foo,裡面定義了apply方法。有了這個apply方法以後,我們在呼叫這個Foo類的時候,用函式的方式來呼叫:

object Client {

    def main(args: Array[String]): Unit = {
        val foo = Foo("Hello"
) } }

我們用Foo("Hello")的方式,就得到了一個Foo型別的物件,這一切就是apply方法的功勞。如果沒有apply方法,我們將需要使用new關鍵字來得到Foo物件。

2.apply方法用來做工廠

apply方法的最佳實踐方式之一就是用來做工廠。比如在Scala的標準庫中,許多集合類給我們提供了apply方法來建立集合:

object Client {

    def main(args: Array[String]): Unit = {
        val arr = new Array[Int](3)
        arr(0) = 0
        arr(1
) = 1 arr(2) = 2 arr.foreach(x => print(x + " ")) println() val array = Array(1,2,3) array.foreach(x => print(x + " ")) } }

上面兩種方式我們都可以用來建立Array。第一種方式是使用new關鍵字,這是傳統的面向物件的方式。那麼第二種方式是什麼情況呢?如果我們在IDE裡點進去,可以發現IDE會提示我們有一個apply方法。點進去看apply方法的原始碼:

  /** Creates an array of `Int` objects */
// Subject to a compiler optimization in Cleanup, see above. def apply(x: Int, xs: Int*): Array[Int] = { val array = new Array[Int](xs.length + 1) array(0) = x var i = 1 for (x <- xs.iterator) { array(i) = x; i += 1 } array }

3.unapply方法

從上面的例子不難看出,apply方法有點類似於java中的建構函式,接受構造引數變成一個物件。那麼unapply方法就剛好相反,他是接受一個物件,從物件中提取出相應的值。
unapply方法主要用於模式匹配中。
看個簡單的例子:

class Money(val value: Double, val country: String) {}

object Money {
    def apply(value: Double, country: String) : Money = new Money(value, country)

    def unapply(money: Money): Option[(Double, String)] = {
        if(money == null) {
            None
        } else {
            Some(money.value, money.country)
        }
    }
}

客戶端實現:

    def testUnapply() = {
        val money = Money(10.1, "RMB")
        money match {
            case Money(num, "RMB") =>  println("RMB: " + num)
            case _ => println("Not RMB!")
        }
    }

最後輸出為:

RMB: 10.1

所以下面那種建立陣列的方式,其實是通過Array類的apply方法實現的。