`
诺铁
  • 浏览: 35377 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

诺铁的scala入门心得 for java程序员

阅读更多

看完了Martin Odersky的《Programming in Scala》。作者是写java编译器的大牛,技术够强,书写的一般,我个人感觉如果是被“scala是更好的java”这句传言吸引而来的的java程序员,恐怕会很快被吓跑----scala的代码跟java代码实在是太不一样。反而如果之前学过haskell这样的纯函数式编程语言,学scala不会有太多障碍。我个人建议想学scala的程序员先看完learnyourhaskellforgreatgood ,对函数式编程有个纯粹的认识后再来看scala在java虚拟机上能实现到什么程度。

 

我写这篇博客记录一下我觉得对java程序员来说比较需要掌握的scala编程要素

 

  1. scala解释器
    下载安装装好scala,把bin加入path, 然后可以用文本文件编写scala脚本,在命令行下运行scala -i filepath加载脚本文件,然后就可以在scala提示符scala>里面“玩弄”你写在脚本里的函数,对象等等
    修改了文件后可以在scala>里面输入:l filepath来加载 
    用好解释器对学习scala非常有帮助,所以特别说一下
  2. 头等函数(first-class function)
    函数跟类一样是顶级元素,所以可以直接在代码里定义函数,不需要放在类里作为“方法”
    def sum(x:Int, y:Int, z:Int) :Int = {
      x + y + z
    }
     
    scala>sum(1,2,3)
    res0: Int = 6
     头等函数跟变量一样可以传递,可以被赋值(scala里需要以偏函数的形式,haskell可以直接赋值)
    scala>val s = sum _   //sum函数赋值给变量s
    scala>s(1,2,3)            
    res: Int = 6
  3. 函数字面值
    可以不给函数起名字,直接把函数定义赋值给变量
    scala> val s2 = (x:Int, y:Int ,z:Int) => x + y + z
    s2: (Int, Int, Int) => Int = <function3>
    
    scala> s2(1,2,3)
    res1: Int = 6
     有必要认识函数的这种写法,因为会有助于看懂scala的库里的接口,比如List类里的filter方法
    def filter (p: (A) ⇒ Boolean): List[A]
    这个函数接受一个谓词(其实就是一个函数)p,这个p无所谓名字,只要是能够接受一个元素作为参数,返回Boolean型就行了
    scala> val l1 = List(1,2,3,4,5)
    l1: List[Int] = List(1, 2, 3, 4, 5)
    
    scala> l1.filter(x => x > 3)  //过滤出大于三的结果,返回到新集合里
    res4: List[Int] = List(4, 5)
    
    scala> l1.filter(x => x % 2 == 0)  //过滤出偶数
    res7: List[Int] = List(2, 4)
  4. 占位符和偏函数(partially applied function,也有翻译为部分应用函数的)
    占用符,就是_, 看scala的代码会看到大量的_, 
    有些地方这个_的意思跟*一样作为通配符,只是scala里*不是内置语法元素,是可以用来做方法名和函数名的,以便用户可以方便开发自己的DSL
    scala> def *(x:Int, y:Int) = x * y  //用*作为函数名
    $times: (x: Int, y: Int)Int
    
    scala> *(2,3)
    res8: Int = 6
     scala> import scala.collection._
    import scala.collection._
    这个就是跟*一样的效果了
    
     更重要的作用是用做偏函数的占位符,比较给力
    scala> def sum(x:Int, y:Int, z:Int):Int = x + y + z
    sum: (x: Int, y: Int, z: Int)Int
    
    scala> val s = sum(2, 3, _:Int)
    
    在这里,给sum函数传入2,3作为前两个参数,但是不传入第3个函数,而是传入一个占位符,于是产生了只接受一个参数的函数s
    s: (Int) => Int = <function1>  //函数的签名变成了一个参数
    
    scala> s(4)                                // 2 + 3 + 4
    res9: Int = 9
    
    这个东东就是所谓的偏函数(部分应用函数)
    
     占位符的应用可以很灵活,可以占任何位置
    scala> def say(greeting:String, title:String, name:String) = println(greeting + "," + title + " " + name)
    say: (greeting: String, title: String, name: String)Unit
    
    scala> val callNotyy = say(_:String, "Mr", _:String)
    callNotyy: (String, String) => Unit = <function2>
    
    scala> callNotyy("hello","notyy")
    hello,Mr notyy
     
  5. 模式匹配
    用函数式编程的风格写代码首先要适应的就是“模式匹配”,先来个简单的例子
    def sayInt(i:Int): String = i match {
      case 1 => "one"
      case 2 => "two"
      case 3 => "three"
      case _ => "unknown int"   //_作为通配符,提供一个默认case
    }
    
    scala> sayInt(1)
    res0: String = one
    
    scala> sayInt(2)
    res1: String = two
    
    scala> sayInt(4)
    res4: String = unknown int
    从最基本的概念来说和switch很像,但是灵活的多,上例只是最简单的常量模式匹配。
     模式匹配机制可以匹配各种“东西”,比如说匹配一个列表中的元素:
    def zeroStartList(l:List[Int]) = l match {
      case List(0, _, _) => println("found it") //匹配3个元素的列表,并且第一个元素是0
      case _ => println("not found")
    }
    
    scala> zeroStartList(List(0,1,2))
    found it
    
    scala> zeroStartList(List(1,1,2))
    not found
     还可以匹配类型
    def size(x: Any) = x match {
      case s: String => s.length
      case m: Map[_, _] => m.size
      case _ => 1
    }
    
    scala> size("abc")
    res7: Int = 3
    
    scala> size(Map(1 -> 'a', 2->'b'))
    res11: Int = 2
     
  6. case class与模式匹配还有守卫(guard)
    构造器模式匹配是模式匹配的真正强大之出,但是需要引入样本类(case class)的概念
    case class User(name:String, age:Int, position:String)
    
    def sayHello(user:User) = user match {
      case User(name, _, "admin") => println("hello,admin " + name)
      case User(_, _, _) => println("how do you get here! guards!!")
    }
    这个模式匹配可以理解为“形如”,意会吧,看到这里,上面两行代码应该不难理解吧
    scala> sayHello(User("notyy",35,"admin"))
    hello,admin notyy
    
    scala> sayHello(User("badguy",35,"thief"))
    how do you get here! guards!!
    
    
     构造器模式可以深层匹配,稍微改下代码:
    case class Email(name:String,domain:String)
    
    case class User(name:String, age:Int, position:String, email:Email)
    
    def sayHello(user:User) = user match {
      case User(name, _, "admin",Email(_, "notyy.iteye.com")) => println("hello,admin " + name)
      case User(_, _, _, _) => println("how do you get here! guards!!")
    }
    这里我们不仅匹配User里的内容,还匹配到User里的Email里的内容
    
    scala> sayHello(User("notyy",35,"admin",Email("notyy","somedomain.com")))
    how do you get here! guards!!
    
    scala> sayHello(User("notyy",35,"admin",Email("notyy","notyy.iteye.com")))
    hello,admin notyy
     我们再来结合guards,以便对参数进行更细致的匹配:我们改下上面的代码,对年龄不满18的用户进行限制
    def sayHello(user:User) = user match {
      case User(name, age, _, _) if age < 18 => println("you are too young to come here," + name + " ;-) ,guards!")
      case User(name, _, "admin",Email(_, "notyy.iteye.com")) => println("hello,admin " + name)
      case User(name, _, _, _) => println("how do you get here!" + name + ", guards!!")
    }
    
    scala> sayHello(User("notyy",17,"admin",Email("notyy","notyy.iteye.com")))
    you are too young to come here ;-) ,guards!
    
     

  7. for 表达式
  8.  for循环要拿出来说一下。如果是从纯函数式编程语言如haskell转过来,会知道函数式编程语言里一般木有循环的。代之的是递归。更常用的是一些通用的循环函数框架,foreach, filter, map等
    val users = List(
      User("tom", 17, "admin", Email("tom", "notyy.iteye.com")),
      User("notyy", 35, "admin", Email("notyyy", "notyy.iteye.com")),
      User("badguy", 35, "admin", Email("badguy", "badguys.com"))
    )
    
    scala> users.foreach(sayHello)
    you are too young to come here,tom ;-) ,guards!
    hello,admin notyy
    how do you get here!badguy, guards!!
    
    List类里的foreach方法的定义是
    def foreach (f: (A) ⇒ Unit): Unit
    [use case] Applies a function f to all elements of this list
    这方法的意思就是对集合的每个元素应用传入进来的函数f
     这是我喜欢的编码风格,不过喜欢for循环的也可以用scala里的for表达式
    for (user <- users)
      sayHello(user)
     还可以在for里面结合模式匹配。。。
    for (User(name,_ ,pos ,_) <- users)
      println("name=" + name + ",pos=" + pos)
     如此强力。。。
    scala的特性太多,语法糖多的有点甜腻,写完此文总算记住了一些,接下来研究liftweb框架,用上面那些基础基本上可以看下去了。《scala编程》这本书作为入门书虽然是艰深了点,作为参考手册倒是相当不错的,可以常备案头常翻翻

分享到:
评论

相关推荐

    SCALA程序设计-JAVA虚拟机多核编程实战

    3. Scala的学习资料:本书《Scala程序设计:Java虚拟机多核编程实战》是由Venkat Subramaniam所著,郑有李剑翻译,是一本为Java程序员所写,讲授Scala编程的书籍。书中包含了对Scala的函数式编程基础的介绍,涵盖了...

    scala入门(仅供参考)

    本篇文章主要面向有一定Java开发经验的程序员,旨在帮助他们入门Scala。 ### 1. Scala简介 Scala是由Martin Odersky设计的一种静态类型的编程语言,它的名字来源于"Scalable Language"的缩写,表明它能够从小规模...

    2018 Scala for Java Developers: A Practical Primer

    Master the fundamentals of Scala and understand its emphasis on functional programming that sets it apart from Java. This book will help you translate what you already know in Java to Scala to start ...

    写给Python程序员的Scala入门教程1

    【标题】:“写给Python程序员的Scala入门教程1” 【描述】:本教程旨在帮助熟悉Python的程序员逐步学习Scala语言,特别关注如何利用已有的Python背景来理解和掌握Scala的特性和用法。教程将探讨Scala在大数据处理...

    Scala入门学习教程.docx

    Scala入门学习教程 本资源摘要信息为 Scala 入门学习教程,旨在帮助读者快速掌握 Scala 语言的基本概念和编程技术。该教程面向具有一定编程经验的读者,尤其是 Java 语言的开发者。 知识点一:Scala 语言简介 ...

    scala-to-java:将Scala代码转换为Java代码的命令行工具

    Scala到Java 用Scala编写的简单工具,揭示了Scala编译器的奥秘。 从StdIn读取scala代码,并将其反编译的Java版本写入StdOut。 用法 确保您已安装Java 1.8和Maven 检出项目 在项目目录中调用mvn clean package 。 ...

    Scala编程语言详解(从入门到精通)spark

    - **`for` 表达式**:Scala 的 `for` 表达式支持生成器风格的迭代,可以嵌套循环。 - **函数**:Scala 中的函数可以作为参数传递给其他函数,也可以作为返回值。 - **过程**:Scala 还支持过程,即不返回值的函数。 ...

    Scala for Java Developers(PACKT,2014)

    Scala for Java Developers is a step-by-step guide full of easy-to-follow code taken from real-world examples explaining the migration and integration of Scala in a Java project. With this book, you ...

    Scala for the Impatient

    Scala的设计哲学是简洁至上,旨在让程序员摆脱Java中的繁杂语法,从而快速上手并提升编码效率。Scala还具有静态类型特性,这有助于编译器在代码运行前发现错误,从而节省调试时间。 Scala语言的一个亮点是它支持...

    SpringBoot + SpringData Jpa + Scala + Mysql(java+Scala混编)

    在Java项目中使用Scala,通常被称为Java和Scala的混编。这种混编允许开发团队在已有的Java项目中逐渐引入Scala代码,以利用其优势,同时保持与现有Java代码的兼容性。在实际应用中,可能会在服务端逻辑或者特定组件...

    scala 入门PDF文档,编码规范文档 scalabook.rar

    scala 入门PDF文档,编码规范文档。 Scala 是一门多范式(multi-paradigm)的编程语言,设计初衷是要集成面向对象编程和函数式编程的各种特性。 Scala 运行在 Java 虚拟机上,并兼容现有的 Java 程序。

    Scala程序设计_Java虚拟机多核编程实战

    本书循序渐进地介绍了Scala的函数式编程基础,虽然篇幅短小,却切中要害。读者可以学会使用Scala静态语言的强大功能创建简洁、可扩展、高度可并行的代码。对于多核时代JVM上的并发编程,Scala是绝好的工具,而本书是...

    为Java虚拟机编译Scala(Michel Schinz)Compiling Scala for the Java Virtual Machine (Michel Schinz)

    但从提供的信息可以看出,为Java虚拟机编译Scala涉及了编程语言设计的深层次概念,如mixin继承、运行时类型处理、类型擦除、并发控制、类型表示等。这些内容展示了Scala语言在保证与JVM良好的集成性的同时,如何在...

    Java程序员简历模板

    - **Java和Scala开发**:Java是主流的后端开发语言,Scala则是面向现代并发系统的高性能编程语言,两者结合显示了程序员在多范式编程上的能力。 - **设计模式**:熟悉常用设计模式,表明程序员具备良好的代码组织...

    Scala程序设计:Java虚拟机多核编程实战1

    《Scala程序设计:Java虚拟机多核编程实战》是一本专为程序员和有经验的Java开发者设计的书籍,旨在引导读者掌握Scala语言,利用其功能强大的特性进行并发编程。Scala是一种融合了函数式和面向对象编程特点的静态...

Global site tag (gtag.js) - Google Analytics