`
spartan1
  • 浏览: 366011 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

scala语言学习之Option

 
阅读更多

前两天看到有篇关于Option的小文章,上面引用NullPointer的发明人C.A.R. Hoare老先生说的一句话:空引用是一个“十亿美元的错误”(http://en.wikipedia.org/wiki/Null_pointer#Null_pointer)。

 

当时以为这里主要说的是返回值为空时会导致出现空指针异常,而返回值如果用Option包一下,就总会返回一个对象,再也不会返回空引用了,也不会有NullPointerException了。这种认识没有错,不过直到今晚看play框架的初始化代码,才清楚认识到Option到底有什么用处,到底如何能节省“10亿美元”。

 

play框架初始化时会根据配置创建一个NettyServer,过程如下:

 

  def main(args: Array[String]) {
    args.headOption.orElse(
      Option(System.getProperty("user.dir"))).map(new File(_)).filter(p => p.exists && p.isDirectory).map { applicationPath =>
        createServer(applicationPath).getOrElse(System.exit(-1))
      }.getOrElse {
        println("Not a valid Play application")
      }
  }

 初看有点晕,这么长的一串,又是map,又是filter,还不断有orElse,getOrElse,搞不懂到底是什么意思。只好回过头来先研究下Option的代码:

 

 @inline final def getOrElse[B >: A](default: => B): B =
    if (isEmpty) default else this.get

 可以看出,getOrElse的意思是,如果Option为空,就返回参数的值,否则返回Option的值。顺便插一句,这里的参数值类型前有个“=>”,是延后求值的,就是所谓的call-by-name参数:如果Option不为空,参数根本就不会求值。看到这里,想起了我们产品代码中一堆如下java代码:

 

if (log.isDebugEnabled())
{
    log.debug("plaplapla");
}

 如果用scala,把log.debug的参数定义为call-by-name的参数,就只有一行搞定。C++中的做法是定义一个宏,也是很难看的解决方案。

 

再看map:

 

  @inline final def map[B](f: A => B): Option[B] =
    if (isEmpty) None else Some(f(this.get))

 如果Option为空,返回空Option,否则返回经过函数f映射后的Option。这里的None和Some是Option的子类,分别代表没有和有。

 

filter类似:

 

  @inline final def filter(p: A => Boolean): Option[A] =
    if (isEmpty || p(this.get)) this else None

 如果为空,或者p函数返回false,返回空Option,否则返回自己。

 

再回过头看最初的5行代码,立刻感觉到Option的巨大优势了:做了这么多参数准备和验证,又是判断空,又是判断文件是否存在以及是否为目录,居然没有任何if语句!没有if else的一个副作用是错误处理也非常优雅。这段代码如果用java写的话,大概是这样子的:

 

public static void main(String[] args) {
    String dir = null;
    if (args.length == 1)
      dir = args[0];
    else
      dir = System.getProperty("user.dir");

    if (dir != null)
    {
      File f = new File(dir);
      if (f.exists() && f.isDirectory())
      {
         NettyServer server = createServer(f);
         if (server == null)
            System.exit(-1);
      }
      else
    	  System.out.println("not a valid play application");
    }
    else
       System.out.println("xxxx");
 }

 代码行长短先不说,以前感觉这种java代码逻辑很清晰,现在却觉得这些if else这么别扭,错误处理这么难受。

 

再回过头来看scala的其他代码,发现基本上没有if语句。这种感觉有点像前两天刚刚开始用erlang的时候,发现erlang代码中几乎没有if语句一样,最初极其别扭,发现不会写程序了,不过很快,就是用case语句爽得很了。

 

看了scala,不想写java了。

 

分享到:
评论

相关推荐

    最好的scala学习 课件

    Scala是一种强大的多范式编程语言,它融合了面向对象和函数式编程的特性,被广泛应用于大数据处理...通过深入学习和实践,你不仅可以掌握Scala语言,还能有效利用Scala在大数据分析和处理项目中发挥出Spark的强大性能。

    学习scala好的项目

    总的来说,"学习scala好的项目"提供了一个全面的平台,让初学者能够系统地学习Scala语言,并结合Spark进行大数据处理实践。通过这个项目,学习者不仅能掌握Scala的基本语法和概念,还能熟悉Spark框架的应用,从而在...

    Programming In Scala 中文版及英文版

    总之,《Programming In Scala》中文版和英文版覆盖了Scala语言的核心概念和高级特性,无论是初学者还是有经验的开发者,都能从中获益匪浅。通过深入学习和实践,开发者能够掌握Scala的精髓,运用到实际项目中,提升...

    Scala函数式编程

    4 开发成本比java小,但是语言学习成本比java高很多 正在阅读这本书的过程中,只能一点一点说。 第一部分快要读完了,习题也快要做完了。 1 第一部分主要着墨点正是回答我上述问题的1,2,3的。很大篇幅都放在,...

    scala-2.12.2 api 最新 离线文档

    最新版的Scala API离线文档为2.12.2,这是对Scala语言的一个稳定更新,提供了许多改进和新功能。 首先,`scala-reflect`模块是Scala的反射库,它允许在运行时检查和修改程序结构。反射在许多场景下非常有用,例如元...

    scala-2.12.8 源码包

    Scala是一种强大的多范式编程...总的来说,Scala-2.12.8源码包是学习和研究Scala语言、函数式编程、并发处理和JVM优化的理想资源。通过深入研究源码,开发者不仅可以提升编程技能,还能更好地利用Scala解决实际问题。

    Scala编程实战基础教程

    例如,Scala中的Option类型可以用来处理可能的null值,避免空指针异常,这是很多其他语言中常见的问题。 函数式编程是Scala的一个核心特色。在Scala中,函数是第一等公民,可以作为参数传递,也可以作为返回值。...

    Scala 讲座.rar

    在“Scala讲座:Scala语言探险一(3).pdf”和“Scala讲座:Scala语言探险二(3).pdf”中,可能包含了对Scala的初识和进一步探索。这些章节可能涵盖基本的控制流结构,如if-else、循环,以及如何使用Scala进行异常...

    atomic-scala-examples

    《原子Scala示例》是基于Scala编程语言的一系列实践代码,源自知名编程书籍《Atomic Scala》。这本书旨在帮助读者深入理解Scala的编程理念和语法特性,通过实例化学习,让初学者和经验丰富的开发者都能从中受益。这...

    scala源码-2.11.x.zip

    总之,Scala源码2.11.x是一个深入学习Scala编程语言的宝贵资料,涵盖了编译器、标准库、类型系统、特性实现等多个方面。通过阅读和分析这些源码,开发者不仅可以提升对Scala的理解,还能汲取其设计思想,提高自己的...

    scala-doc-2.11.8 原版

    在"scala-docs-2.11.8"这个压缩包中,你将找到Scala语言的所有官方文档,包括但不限于以下几个方面: 1. **基础语法**:Scala的基础语法与Java有很多相似之处,但也有其独特的特点,如模式匹配、高阶函数、类型推断...

    scala 案例

    Scala是一种强大的多范式编程语言,它融合了面向对象和函数式编程的特性。这个"Scala案例"可能包含了各种使用Scala编程的实际示例,旨在帮助学习者深入理解其语法、特性和实际应用。以下是关于Scala的一些核心知识点...

    头歌Scala中集合的使用

    Scala中集合的使用 大学生 1. List 列表的使用 2. Set 集合的使用 3.Map 映射的使用 4. 元组的使用

    scala-docs-2.11.8.rar

    2. **Scala语言构造**:如类、特质、枚举、包、对象、变量、常量等的定义和用法。 3. **泛型**:Scala的泛型提供了类型参数化,使得代码更具通用性。 4. **Option类型**:Scala的Option类型用于处理可能的空值,避免...

    快学Scala-[中文]

    Horstmann 撰写,并由高宇翔翻译成中文,得到了 Martin Odersky(Scala 语言的设计者之一)的序言推荐。这本书于2012年10月由电子工业出版社首次出版,旨在帮助读者快速掌握 Scala 的核心概念和应用。 **Scala ...

    一些scala实例

    **描述:** 这个资料包包含了一些使用Scala编程语言编写的实例程序,目的是为了帮助学习者通过实践对比Scala与Java的差异,从而更好地理解和掌握Scala的优势和特点。通过这些实例,我们可以深入探索Scala的语法、...

    Scala2.12.8源码包

    这个“Scala2.12.8源码包”包含了Scala语言版本2.12.8的所有源代码,是深入理解Scala语法、类型系统以及其运行机制的重要资源。 1. **Scala简介**:Scala由EPFL(瑞士洛桑联邦理工学院)的Martin Odersky教授领导...

Global site tag (gtag.js) - Google Analytics