本專題介紹 Scala 的參數(shù)化類型,在介紹的過(guò)程中同時(shí)演示了信息隱藏的技術(shù),這里我們通過(guò)實(shí)現(xiàn)一個(gè)純函數(shù)化實(shí)現(xiàn)的隊(duì)列來(lái)舉例說(shuō)明。
參數(shù)化類型幫助你實(shí)現(xiàn)通用的類型和 Trait。比如通用的集合類 Set,該通用集合類可以通過(guò)制定類型參數(shù) T,Set[T],它通過(guò)實(shí)例化參數(shù)類型,可以定義 Set[String],Set[Int] 等等。
此外,一般來(lái)說(shuō) String 是 AnyRef,但在其它一些語(yǔ)言中,Set[String] 并一定是 Set[AnyRef] 的子類。在 Scala 中可以通過(guò)制定參數(shù)化類型之間的繼承屬性的 Variance 特性,來(lái)說(shuō)明該參數(shù)化類型中使用不同的參數(shù)類型后的類型之間是否也存在繼承關(guān)系。
首先我們定義一些我們要實(shí)現(xiàn)的這個(gè)簡(jiǎn)單的對(duì)象的一些基本需求:
這個(gè)函數(shù)化隊(duì)列要求支持下面三個(gè)基本操作:
和一般隊(duì)列實(shí)現(xiàn)不同的是,函數(shù)化隊(duì)列實(shí)現(xiàn)時(shí)不改變隊(duì)列的內(nèi)容,當(dāng)需要修改隊(duì)列時(shí)構(gòu)造一個(gè)新隊(duì)列。
如何構(gòu)造一個(gè)效率高的隊(duì)列呢?也就是 head,tail,enqueue所花費(fèi)的時(shí)間不應(yīng)當(dāng)隨隊(duì)列的大小而改變,一個(gè)簡(jiǎn)單的實(shí)現(xiàn)可以使用 List 類來(lái)實(shí)現(xiàn),但 enqueue 操作的時(shí)間和隊(duì)列的長(zhǎng)度成正比,這里給出一個(gè)使用兩個(gè) List 對(duì)象的隊(duì)列實(shí)現(xiàn),具體算法不解釋了(本專題側(cè)重點(diǎn)不在算法本身)可以實(shí)現(xiàn)一個(gè)高效的隊(duì)列操作。
class Queue[T](
private val leading:List[T],
private val trailing:List[T]
){
private def mirror =
if(leading.isEmpty)
new Queue(trailing.reverse,Nil)
else
this
def head=mirror.leading.head
def tail={
val q= mirror
new Queue(q.leading.tail,q.trailing)
}
def enqueue(x:T)=
new Queue(leading,x::trailing)
}
使用這個(gè)實(shí)現(xiàn),進(jìn)行一些基本的隊(duì)列操作:
scala> val q = new Queue(List(1,2,3),Nil)
q: Queue[Int] = Queue@24cc40b6
scala> val q1 = q enqueue 4
q1: Queue[Int] = Queue@67825189
scala> q
res0: Queue[Int] = Queue@24cc40b6
scala> val p = q1 head
p: Int = 1
scala> q1
res1: Queue[Int] = Queue@67825189
這個(gè)實(shí)現(xiàn)滿足功能需求,但我們希望可以實(shí)現(xiàn)如下的形式:
scala> val q = Queue(1,2,3)
q: Queue[Int] = Queue(1,2,3)
scala> val q1 = q enqueue 4
q1: Queue[Int] = Queue(1,2,3,4)
scala> q
q: Queue[Int] = Queue(1,2,3)
在之后的文章我們逐步的優(yōu)化這個(gè)實(shí)現(xiàn)。