自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Kestrel.scala中的QueueCollection

開發(fā) 后端
本文介紹了Scala中的QueueCollection。這是一個(gè)Scala的比較特殊語法。文章中還包括了HashMap的創(chuàng)建方法。

有關(guān)Kestrel的Scala實(shí)例已經(jīng)介紹到了第三篇,接下來介紹Scala中的一個(gè)走讀分支:QueueCollection。

在Kestrel.scala的startup方法中,告訴我們接下來有兩個(gè)走讀的分支,一個(gè)是QueueCollection和PersistentQueue。另一個(gè)是KestrelHandle。KestrelHandle是和NioSocketAcceptor相聯(lián)系的,所以可以想想KetrelHandle是用來處理鏈接……與之相關(guān)的還有memcache目錄下的Codec.scala。

我們先忽略Kestrel.scala在startup中的幾個(gè)語法細(xì)節(jié),從相對(duì)比較簡單的QueueCollection開始吧:

  1. class QueueCollection(queueFolder: String, private var queueConfigs: ConfigMap) {  
  2.   ……  
  3.   if (! path.isDirectory) {  
  4.     path.mkdirs()  
  5.   }  
  6.   ……  
  7. }  

這是一個(gè)Scala的比較特殊語法。class本身就是一個(gè)建構(gòu)函數(shù)。程序中queueFolder和queueConfigs是創(chuàng)建是必須的兩個(gè)參數(shù)。class在Scala里面就支持一種建構(gòu)函數(shù)。這里的參數(shù)也可以看做是整個(gè)class的變量,所以程序中的private只表示在類以外的地方,沒有辦法獲取queueConfigs這個(gè)參數(shù)。

接下來是關(guān)于HashMap的創(chuàng)建:

  1. private val queues = new mutable.HashMap[String, PersistentQueue]  
  2.  

我們知道HashMap是有兩個(gè)類型,一個(gè)是鍵的類型,一個(gè)是值的類型。在queues里面,String就是鍵,PersistentQueue就是值。這跟Java/C++的模板累死,不需要特別的解釋了。

然后是一個(gè)很多地方都用到的Count,在Count.scala里面有說明,就是一個(gè)統(tǒng)計(jì)技術(shù)的類,寫法很干凈,注意里面的函數(shù)定義,都沒有用大括號(hào)。多看幾遍就熟悉,Scala是怎么定義函數(shù)的了。顯然,這看起來更像是命令,而不是函數(shù)體的聲明。

經(jīng)過兩段比較好理解的代碼之后,出現(xiàn)了一段恐怖的代碼:

  1. queueConfigs.subscribe { c =>  
  2.   synchronized {  
  3.     queueConfigs = c.getOrElse(new Config)  
  4.   }  
  5. }  

如果只是看這段代碼,就有種喉嚨被卡住,咽不下去又吐不出來的感覺。這段代碼做了些什么,大家都能猜出來,郁悶的是,這到底遵循的是那個(gè)語法規(guī)范呢?咋代碼就寫得那么四不像呢?不過如果我們回過來看一下net.lag.configgy.configMap中subscribe的定義,似乎就能明白多一點(diǎn):

  1. def subscribe(f: (Option[ConfigMap]) => Unit): SubscriptionKey = {  
  2.   subscribe(new Subscriber {  
  3.     def validate(current: Option[ConfigMap], replacement: Option[ConfigMap]): Unit = { }  
  4.     def commit(current: Option[ConfigMap], replacement: Option[ConfigMap]): Unit = {  
  5.       f(replacement)  
  6.     }  
  7.   })  
  8. }  
  9.  

看來還是有點(diǎn)難度——呃,其實(shí)這是Kestrel的一個(gè)非常靈活的功能,定義作為參數(shù)的函數(shù)的類型:

  1. func_name : (param_type1, param_type2) => Unit  

func_name是一個(gè)有兩個(gè)參數(shù)的函數(shù),參數(shù)類型分別是param_type1和param_type2。所以subscribe的參數(shù)是一個(gè)有一個(gè)參數(shù)的函數(shù),這個(gè)參數(shù)所以O(shè)ption[ConfigMap]。關(guān)于Option, Some的話題,我們稍后再談。這已經(jīng)不影響程序的閱讀了。

回到在QueueCollection.scala的代碼,當(dāng)我們知道subscribe的參數(shù)是一個(gè)函數(shù)的時(shí)候,下面這段代碼的作用就是,當(dāng)queueConfigs的某些狀態(tài)變化的時(shí)候,會(huì)調(diào)用一個(gè)叫commit的內(nèi)部函數(shù),而這個(gè)內(nèi)部函數(shù)的功能,就是把新替換的配置,作為參數(shù)c,傳遞給這段代碼,結(jié)果是queueConfigs = c.getOrElse(new Config)。涵義是,如果不存在就添一個(gè)缺省值。

  1. queueConfigs.subscribe { c =>  
  2.   synchronized {  
  3.     queueConfigs = c.getOrElse(new Config)  
  4.   }  
  5. }  

繞了一圈,其實(shí)是定義了一個(gè)觸發(fā)器,并且觸發(fā)器的作用是,當(dāng)設(shè)置是空置的時(shí)候,補(bǔ)上一個(gè)標(biāo)準(zhǔn)的缺省值。完全是殺雞用了牛刀。但是回過來我們重新考慮Scala對(duì)架構(gòu)上的意義,這種把函數(shù)作為參數(shù)的做法,可以很方便的實(shí)現(xiàn)callback操作,當(dāng)然這需要配合上object這樣的類,否則尋找對(duì)應(yīng)的callback類,還需要費(fèi)點(diǎn)周章。

隨后,我們看到了著名的閉包(closure),而且一來還來了兩段,第一段是filter,對(duì)于所有的成員“name”,如果 => 后面的內(nèi)容返回是成功的話(如果name不包含~~),就添加到list里面去。

  1. def loadQueues() {  
  2.   path.list() filter { name => !(name contains "~~") } map { queue(_) }  
  3. }  
  4.  

第二段是把list變成一個(gè)map,完整的寫法應(yīng)該是

  1. map { _ => queue(_) }  
  2.  

很多時(shí)候不需要寫成那么麻煩,可以直接把 _ => 給省略了。有時(shí)候因?yàn)榱?xí)慣的原因,你會(huì)猜想queue又是一個(gè)什么特殊的語法?其實(shí)它一點(diǎn)都不特殊,往下大概10行左右,就是它的定義。queue,是把一個(gè)字符串的隊(duì)列名,轉(zhuǎn)變成一個(gè)真正的PersistentQueue的函數(shù)。所以load_queues,在大體上起了初始化隊(duì)列的作用。

后面的段落中還有一個(gè)使用了closure的語法:

  1. def currentItems = queues.values.foldLeft(0L) { _ + _.length }  
  2.  

查詢一下foldLeft的函數(shù)說明如下:

  1. def  foldLeft[B](z : B)(op : (B, A) => B) : B  
  2.  

根據(jù)函數(shù)的定義,foldLeft的函數(shù),就是用迭代的方法,把所有元素的 length,也就是 _.length 累加起來,最后返回。_.length的總數(shù)。我們從語法上不難發(fā)現(xiàn),{_ + _.length} 可以看做是 { a , b => a + b.length }。

讀到這里,暫時(shí)告一段落。后半段QueueCollection還有一個(gè)重要的Scala語法——case下一次再討論吧。

【編輯推薦】

  1. 走讀Kestrel,了解Scala
  2. 從Kestrel看Scala的核心程序模塊
  3. Scala實(shí)例教程:Kestrel
  4. 從Scala看canEqual與正確的的equals實(shí)現(xiàn)
  5. Scala編程語言
責(zé)任編輯:yangsai 來源: dingsding
相關(guān)推薦

2009-09-22 10:15:42

PersistentQScala

2009-09-28 11:25:17

PersistentQKestrelScala

2009-09-28 11:37:03

Journal.scaKestrel

2009-09-18 11:44:05

Scala實(shí)例教程Kestrel

2009-09-28 11:42:21

KestrelScala

2009-09-28 10:26:12

Scala代碼實(shí)例Kestrel

2009-09-22 09:42:24

Scala的核心

2009-07-22 07:53:00

Scala擴(kuò)展類

2009-07-08 15:35:18

Case類Scala

2009-07-22 07:45:00

Scala代碼重復(fù)

2023-06-12 15:33:52

Scalafor循環(huán)語句

2009-07-21 17:21:57

Scala定義函數(shù)

2009-07-08 12:43:59

Scala ServlScala語言

2010-09-14 15:34:41

Scala

2020-10-31 17:33:18

Scala語言函數(shù)

2009-07-22 08:57:49

Scalafinal

2009-07-21 11:25:03

ScalaRational類

2009-07-20 18:03:26

Scala程序Singleton對(duì)象

2017-03-07 15:13:28

Scala偏函數(shù)函數(shù)

2009-07-21 14:03:00

Scalaif表達(dá)式while循環(huán)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)