Essential Scala: Ice Breaker

作者: 刘光聪 | 来源:发表于2016-07-31 07:58 被阅读184次

    Scala是一门结合OO, FP特性的混血儿,支持多种范式的程序设计语言。本文通过一个简单的例子,开启Scala的破冰之旅。

    需求:将一个字符串序列依次转化为大写

    破冰

    object Strings {
      def upper(strs: String*): Seq[String] = {
        strs.map((s: String) => s.toUpperCase())
      } 
    }
    

    单键对象

    Scala摒弃了static的语义,使用object,体现了Scala纯正的OO血统。诸如静态工厂方法,工具类等实现模式,是Scala单键对象最佳的使用场景。

    变长参数

    strs: String*表示变长的字符串列表,可以向Strings.upper传递任意多的字符串。事实上,strs: String*的真正类型为scala.collection.mutable.WrappedArray,所以strs: String*拥有普通集合类的一般特征,例如调用map方法。

    泛型

    Seq[String]Scala的泛型表示,而非Seq<String>Seq表示一个有序的集合。事实上,strs.map返回的类型实际为scala.collection.mutable.ArrayBuffer,但用户无需感知这个事实,这也体现了「按照接口编程」的良好设计原则。

    一等函数

    (s: String) => s.toUpperCase()是一个函数字面值,或者将其看成一个匿名函数。事实上,它真正的类型为:Function1[String, String],表示入参为String类型,返回值为String的一元函数,从而将FP很优雅地融入到OO的世界之中。

    表达式

    Scala一切都是面向表达式的,包括函数或方法;此外,函数返回值的=语法,也增强了Scala类型推演的能力,而且常常略去显式的return关键字(显式的return,相反削弱了函数返回值自动推演的能力)。

    特殊地,当函数只包含单条语句时,常常略去大括号,使得函数更像表达式,程序因此也变得极其优雅,简单,漂亮。

    def upper(strs: String*): Seq[String] = 
      strs.map((s: String) => s.toUpperCase()) 
    

    类型推演

    事实上,编译器可以很容易地推演出匿名函数的入参类型,函数字面值可以变得更加简单。

    def upper(strs: String*): Seq[String] = 
      strs.map(s => s.toUpperCase()) 
    

    省略括号

    按照惯例,略去s.toUpperCase()的括号,强调函数是无副作用的。

    def upper(strs: String*): Seq[String] = 
      strs.map(s => s.toUpperCase) 
    

    占位符

    因为函数字面值s => s.toUpperCase中的s在函数体内仅出现一次,可以使用「占位符」进一步简化程序。

    def upper(strs: String*): Seq[String] = 
      strs.map(_.toUpperCase) 
    

    重载

    • 第二个upper重载函数,必须显式地声明返回值类型;不能指望根据第一个重载的upper函数能够自动推演其返回值类型。

    • strs: _*是将集合对象展开为变长参数的特殊语法。

    object Strings {
      def upper(strs: String*): Seq[String] = 
        strs.map(_.toUpperCase)
      
      def upper(strs: Array[String]): Seq[String] = 
        upper(strs: String*) 
    }
    

    相关文章

      网友评论

        本文标题:Essential Scala: Ice Breaker

        本文链接:https://www.haomeiwen.com/subject/sjbtsttx.html