scala的apply和unapply方法
阿新 • • 發佈:2018-12-21
當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方法實現的。