Scala中重载的方法语法

时间:2015-03-24 20:41:13

标签: scala

我是学习Scala的新手。这段代码出现在Scala in Action中。我有几个问题。

trait ReadOnly {
    val underlying: MongoDBCollection
    def name = underlying getName
    def fullName = underlying getFullName
    def find(query: Query): DBCursor = {
      def applyOptions(cursor:DBCursor, option: QueryOption): DBCursor = { 
        option match {
            case Skip(skip, next) => applyOptions(cursor.skip(skip), next)
            case Sort(sorting, next)=> applyOptions(cursor.sort(sorting), next)
            case Limit(limit, next) => applyOptions(cursor.limit(limit), next)
            case NoOption => cursor
        }
      }
      applyOptions(find(query.q), query.option)
    }
    def find(doc: DBObject): DBCursor = underlying find doc
    def findOne(doc: DBObject) = underlying findOne doc
    def findOne = underlying findOne
    def getCount(doc: DBObject) = underlying getCount doc
}

1)本节讨论重载函数。在其中我看到find超载。但是,我从来没有见过像这样构建的方法:def find(doc: DBObject): DBCursor = underlying find doc。我只见过这样定义的方法:def find(doc: DBObject): DBCursor = { ... }。怎么能在括号中没有东西的情况下发现超载?它在做什么?

2)本书的这一部分说明了上面的代码,

  

在这里,您使用模式匹配将每个查询选项应用于   find方法返回的结果 - 在本例中为DBCursor。

我知道DBCursor是返回类型,从我最近阅读的Android编程书中我知道游标是一种包含数据的对象。我想知道的是,这是指哪种查找方法,并且不仅仅是DBCursor返回的对象类型的名称而不是实际对象的名称?

3)这本书继续说

  

嵌套的applyOptions函数是递归应用的,因为每个函数都是如此   查询选项可以包装下一个标识的另一个查询选项   变量,当它与NoOption匹配时你会拯救。

我不明白当它说什么时它会说什么?每个查询都可以包含另一个查询"有几个原因。我对这个'包裹'有点困惑。使用的术语,但更大的问题是如何有多个查询可用于包装另一个查询?关于applyOptions它所指的是什么,它也有点含糊不清。

4)代码的match部分是如何实现的?我知道您可以将参数传递给方法,但match是嵌套的,那么它如何接收大小写匹配的参数呢?

1 个答案:

答案 0 :(得分:0)

Scala方法语法

您可能习惯使用Java,其中方法代码总是在一对花括号内。但这在Scala中是不同的,其中方法体只是一个表达式 - 评估某个值的东西(也可能有一些副作用)。恰好在Scala中,代码块也是一个有效的表达式,可以用作方法体。

您可能会问:等待,如果表达式是具有值且块是表达式的东西,那么块的值是什么?

在Scala中,块的“值”是该块中最后一个表达式的值。 例如,find(query: Query)方法的正文值将为applyOptions(find(query.q), query.option) - 这是“返回”值。

<强> DBCursor

在MongoDB中,游标是某种迭代器,可以用来懒惰地从数据库中获取数据。在您的示例中,DBCursorfind方法(两者)返回的对象类型的名称。我不明白你的意思是“实际对象的名字”。

QueryOption包装

仔细阅读 - 作者没有说“查询可以包装另一个查询” - 他说“查询选项可以包装另一个查询选项”。只有一个查询,可能有多个选项,这些选项使用递归结构表示,其中每个选项包含另一个选项,例如

Limit(100, Skip(200, Sort(<sorting>, NoOption)))

applyOption函数通过查看其当前选项,对游标应用适当的操作并继续执行下一个(包装)选项直到最终到达NoOption来完成该嵌套结构。

模式匹配

case Skip(skip, next)可能看起来像一个方法调用,但它不是 - 它只是类似的语法。实际上,它与方法调用完全相反,因为在这里我们不是在某处传递某些参数,而是从某个地方取出一些参数。每个案例都试图解构我们的QueryOption对某些模式。例如,当我们说case Skip(skip, next) => some code时,我们实际上会说:“当我们的选项为Skip时,请将跳过的文档数量从其中调出并称之为skip。另外,请执行当前选项中的next(wrapped)选项并将其命名为next。然后,使用skipnext执行某些操作。“

希望这会带来一些澄清。