看完了Martin Odersky的《Programming in Scala》。作者是写java编译器的大牛,技术够强,书写的一般,我个人感觉如果是被“scala是更好的java”这句传言吸引而来的的java程序员,恐怕会很快被吓跑----scala的代码跟java代码实在是太不一样。反而如果之前学过haskell这样的纯函数式编程语言,学scala不会有太多障碍。我个人建议想学scala的程序员先看完learnyourhaskellforgreatgood ,对函数式编程有个纯粹的认识后再来看scala在java虚拟机上能实现到什么程度。
- scala解释器
下载安装装好scala,把bin加入path, 然后可以用文本文件编写scala脚本,在命令行下运行scala -i filepath加载脚本文件,然后就可以在scala提示符scala>里面“玩弄”你写在脚本里的函数,对象等等
修改了文件后可以在scala>里面输入:l filepath来加载
用好解释器对学习scala非常有帮助,所以特别说一下
- 头等函数(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
- 函数字面值
可以不给函数起名字,直接把函数定义赋值给变量
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)
- 占位符和偏函数(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
- 模式匹配
用函数式编程的风格写代码首先要适应的就是“模式匹配”,先来个简单的例子
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
- 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!
- for 表达式
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)
如此强力。。。
相关推荐
本文是《A Scala Tutorial for Java programmers》英文的翻译. 本文仅在对Scala语言和其编译器进行简要介绍。本文的目的读者是那些已经具有一定编程经验,而想尝试一下Scala语言的人们。要阅读本文,你应当具有基础...
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
主要是面向有一些开发经验的java程序员学习参考使用
Scala for Java Developers. Scala for Java Developers
Scala到Java 用Scala编写的简单工具,揭示了Scala编译器的奥秘。 从StdIn读取scala代码,并将其反编译的Java版本写入StdOut。 用法 确保您已安装Java 1.8和Maven 检出项目 在项目目录中调用mvn clean package 。 ...
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 ...
SpringBoot + SpringData Jpa + Scala + Mysql(java+Scala混编)
资源名称:Scala程序设计:Java虚拟机多核编程实战资源截图: 资源太大,传百度网盘了,链接在附件中,有需要的同学自取。
SCALA程序设计-JAVA虚拟机多核编程实战
不错的spark & scala入门书
scala 入门PDF文档,编码规范文档。 Scala 是一门多范式(multi-paradigm)的编程语言,设计初衷是要集成面向对象编程和函数式编程的各种特性。 Scala 运行在 Java 虚拟机上,并兼容现有的 Java 程序。
本书循序渐进地介绍了Scala的函数式编程基础,虽然篇幅短小,却切中要害。读者可以学会使用Scala静态语言的强大功能创建简洁、可扩展、高度可并行的代码。对于多核时代JVM上的并发编程,Scala是绝好的工具,而本书是...
scala程序员面试算法宝典
scala入门精华讲义,基本命令,详细实例。适合新手作为学习指南
本书介绍Scala基本语法、构造。以及如何将您已经知道的复制java语法转换为Scala,了解Scala除了javabecome之外还提供了哪些功能编程概念和惯用技巧和建议,这些技巧和建议在将现有java项目转换为Scala时非常有用
Scala是一门以Java虚拟机(JVM)为目标运行环境并将面向对象和函数式编程语言的最佳特性结合在一起的编程语言。你可以使用Scala编写出更加精简的程序,同时充分利用并发的威力。由于Scala运行于JVM之上,因此它可以...
赠送jar包:scala-java8-compat_2.11-0.7.0.jar; 赠送原API文档:scala-java8-compat_2.11-0.7.0-javadoc.jar; 赠送源代码:scala-java8-compat_2.11-0.7.0-sources.jar; 赠送Maven依赖信息文件:scala-java8-...
着重于Scala的两个重要概念的编译:mixin继承和运行时类型。 编译技术是在Java虚拟机的上下文中提出的,但可以轻松地适应其他类似环境。