zoukankan      html  css  js  c++  java
  • Scala中的Extractor

    Scala中使用unapply方法可以实现三种extractor(另外使用unapplySeq也可以实现extractor)

    1. def unapply(object: S): Option[(T1, ..., Tn)]
    2. def unapply(object: S): Option[T]
    3. def unapply(object: S): Boolean

    感觉第三种extractor的使用形式有些奇怪。比如,下面是《快学Scala》中的一个例子:

    object Name {
      def unapply(input: String) = {
        val pos = input.indexOf(" ")
        if(pos == -1) None
        else Some(input.substring(0, pos), input.substring(pos + 1))
      }
    }
    object IsCompound {
      def unapply(input: String) = input.contains(" ")
    }
    

      这里定义了两个extractor: Name和IsCompound, 前者返回Option[String], 后者返回Boolean

    可以这么使用这两个extractor

    author match {
      case Name(first, last @ IsCompound()) => ... 
      case Name(first, last) => ...
    }

    问题是:

    1. 怎么理解返回值为Boolean的extractor呢?
    2. IsCompound()后边的()不能省略,也不能像返回option的extractor一样绑定变量,比如IsCompound(isComp), 该怎么理解这种行为呢?

    在这篇文章

    The Neophyte's Guide to Scala Part 1: Extractors

    里找到了答案。


    之所以觉得这种形式比较奇怪,还是对extractor的概念理解得有些模糊,没有搞清楚那种match的形式到底干了个啥。

    拿最简单的形式为例

    object Test extends App{
      val author = "Dan Simmons"
      author match{
        case Name(firstName, lastName) => println(s"""Hello, Mr $lastName""")
        case _ => 
      }
    }

    输出:Hello, Mr Simmons

    首先这是一个pattern matching。当某个case分支匹配成功后,就会执行 =>后的语句。

    那什么样算是匹配成功呢?

    这就跟具体的extractor有关了,对于返回Option的提取器,如果调用unapply方法成功返回Some,就算是成功。对于返回Boolean的提取器,如果调用unapply方法返回true,那就是匹配成功。

    在这个pattern matching里,第一个case使用的Name这个提取器匹配成功,它对author这个字符串进行了“解构”,其结果是定义了两个新的变量:firstName和lastName。

    当使用返回Boolean的extractor时,我们并不是进行解构,而是进行判断。因此,返回Boolean的extractor在进行匹配后,不会定义新变量;但是为了与类型匹配分开,也不能直接用提取器的名字而不跟括号。 返回Boolean的提取器,在使用时,只能使用extractor的名字加上()这种形式。像下面这样

      author match{
        case IsCompound() => println("is compound")//IsCompound()里的()不能省
        case _ =>
      }

    也可以把这两种extractor混合起来

      author match{
        case Name(first, last @ IsCompound()) => println("has a compound last name")
        case Name(first, last) => println("don't has a compound name")
        case _ =>
      }

    第一个case是一种复合匹配,只有当Name这个extractor匹配成功,并且提取出来的第二个变量匹配成功IsCompound()时,整个模式才会匹配成功。在这里@定义了一个变量last,把它绑定到成功匹配了IsCompound的那个值上。

  • 相关阅读:
    [zz]利用__FILE__, __LINE__, __FUNCTION__跟踪调试程序
    [zz]va_start() 和 va_end()函数应用
    [zz]shmdt与shmctl的区别
    [zz]GNU C 扩展之__attribute__ 机制简介 [2]
    Linux errno 错误含义速查
    过滤器的简介
    MyBatis中的原理
    文件上传
    mybatis实体为什么要提供一个无参的构造函数
    为什么要有无参构造方法
  • 原文地址:https://www.cnblogs.com/devos/p/4415720.html
Copyright © 2011-2022 走看看