Kestrel.scala中的PersistentQueue

开发 后端
本文介绍Kestrel中的PersistentQueue,后面还重点介绍了一下Scala中的match和case的用法。

上一篇讲到Kestrel.scala中的QueueCollection,下面将介绍PersistentQueue。

继续走读QueueCollection.scala的代码,因为后面封装的大量方法,都是对queues和fanout_queues的操作,根据定义,这两个变量都是mutable.HashMap[String, XXXX]类型的,所以我们先介绍一下mutable.HashMap的几个在Java中陌生的方法:( scala 的 apidoc 在 http://www.scala-lang.org/docu/files/api/index.html 可以查到)

◆apply (key : A) : B

◆Retrieve the value which is associated with the given key. This method throws an exception if there is no mapping from the given key to a value.

◆get (key : A) : Option[B]

◆Check if this map maps key to a value and return the value if it exists.

◆getOrElse [B2 >: B](key : A, default : => B2) : B2

◆Check if this map maps key to a value. Return that value if it exists, otherwise return default.

◆getOrElseUpdate (key : A, default : => B) : B

◆Check if this map maps key to a value. Return that value if it exists, otherwise put default as that key’s value and return it.

#t#我们发现get和apply在Scala中,是完全相同的功能,但是在get返回值里面的Option究竟是什么意思呢?这个问题从刚开始阅读Scala代码的时候就已经困惑我们很久了。其实查询一下Scala的手册,我们不难发现,这是一个对于NULL的改造,因为在Java里面,有些是面向对象的变量,而有些不是,如果需要在Scala的语言内,保证所有对空的判断是一致的,那么就需要做一点什么。所以Scala设计了Option这个抽象类,以及两个子类Some和None。Option的实例,要么是Some类型,要么是None类型。所以把Option[类型]作为参数传递,也就是把这种类型的空值一并处理了,如果不存在,返回的是None[类型],不需要象apply一样抛出一个异常。

让我们重新读下面这段代码:

  1. private[kestrel] def queue(name: String): Option[PersistentQueue] = synchronized {  
  2.     ……  
  3.       Some(queues.get(name) getOrElse {  
  4.         // only happens when creating a queue for the first time.  
  5.         val q = if (name contains '+') {  
  6.           val master = name.split('+')(0)  
  7.           fanout_queues.getOrElseUpdate(master, new mutable.HashSet[String]) += name  
  8.           log.info("Fanout queue %s added to %s", name, master)  
  9.           new PersistentQueue(path.getPath, name, queueConfigs.configMap(master))  
  10.         } else {  
  11.           new PersistentQueue(path.getPath, name, queueConfigs.configMap(name))  
  12.         }  
  13.         q.setup  
  14.         queues(name) = q  
  15.         q  
  16.       })  
  17.   ……  
  18.   }  

先不要晕,根据之前对Option的理解,我们知道这是一个被Option封装了的PersistentQueue类。我们也知道了所有的Scala方法都不需要return,***一条执行命令的返回值就是这个方法的返回值,所以,在这里,Some(……)就是整个方法的返回值,很高兴,因为方法对返回值的定义是PersistentQueue,所以我们知道Some括号里面的一定也是PersistentQueue。

Some(queues.get(name) ……),很好,因为queues的定义是mutable.HashMap[String, PersistentQueue],所以get返回的就是Option[PersistentQueue]。这个方法貌似已经写完了,后面的到底是在做什么呢?getOrElse,按照定义,就是如果值不存在,那么就做后面{}里面的事情,这样的写法,其实就是对空值的处理。用QueueCollection角度来看,就是当查询queues的时候,这个队列如果不存在,那么就做{}里面的处理,创建一个队列。这里需要注意的是——这个getOrElse不是HashMap的getOrElse,而是Option的getOrElse。

然后读起来就比较顺利了,创建一个q,是PersistentQueue类型的,把它赋值给queues(name)中,加入HashMap表中。***不要忘记把q作为整个函数的返回,也就是Some()的返回。和get(name)存在的时候一样。

有了queue这个函数作为基础,后面读起来就容易很多了,我们就重点介绍一下match和case的用法,在add方法里面有这么一段代码:

  1. queue(key) match {  
  2.   case None => false 
  3.   case Some(q) =>  
  4.     ……  
  5.     val result = q.add(item, normalizedExpiry)  
  6.     if (result) totalAdded.incr()  
  7.     result  
  8. }  

之前我们知道 queue(key)返回的是Option[PersistentQueue],match就是做匹配,根据不同的匹配来执行不同的操作,None,如果这个queue没有查询到,那么就返回false。Some(q),如果queue返回的是一个Some类型,也就是Option有值的时候的返回,那么这个q就是返回的PersistentQueue类型的那个实例!就像函数的参数一样,可以直接使用。

很惊奇吧,刚接触Scala的时候,我几乎无法相信case可以这样做判断。后来我们发现,之所以能够做这种判断,是因为所有的Scala都是被类封装的,并且基于Scala的基类,实现了一个所谓的case class和case object的抽象类,并且实现了基于类的统一的==操作符。这一连串的改变造就了异常强大的Scala的case语法。

至于match…case还能怎么用,参考这个链接 http://programming-scala.labs.oreilly.com/ch03.html#PatternMatching

【编辑推荐】

  1. 走读Kestrel,了解Scala
  2. Kestrel.scala中的QueueCollection
  3. 从Kestrel看Scala的核心程序模块
  4. Scala实例教程:Kestrel
  5. Scala编程语言
责任编辑:yangsai 来源: dingsding.com
相关推荐

2009-09-28 11:25:17

PersistentQKestrelScala

2009-09-22 09:59:40

QueueCollecScala

2009-09-28 11:37:03

Journal.scaKestrel

2009-09-18 11:44:05

Scala实例教程Kestrel

2009-09-28 11:42:21

KestrelScala

2009-09-28 10:26:12

Scala代码实例Kestrel

2009-09-22 09:42:24

Scala的核心

2009-07-22 07:45:00

Scala代码重复

2009-07-22 07:53:00

Scala扩展类

2009-07-08 15:35:18

Case类Scala

2023-06-12 15:33:52

Scalafor循环语句

2009-07-21 17:21:57

Scala定义函数

2009-07-08 12:43:59

Scala ServlScala语言

2010-09-14 15:34:41

Scala

2020-10-31 17:33:18

Scala语言函数

2009-07-22 08:57:49

Scalafinal

2009-07-21 11:25:03

ScalaRational类

2009-07-20 18:03:26

Scala程序Singleton对象

2017-03-07 15:13:28

Scala偏函数函数

2009-07-21 14:03:00

Scalaif表达式while循环
点赞
收藏

51CTO技术栈公众号