`

从Java到Scala

阅读更多

 

如果你是一名Java程序员,并且关注这编程语言方面的发展,比如经常去TIOBE网站了解编

程语言流行度排行,那么你应该听说过Scala,如果你还没有开始学习Scala,或者打算下个礼拜

开始学的话,请先看看下面这篇文章,看看能不能改变你的想法。下面的内容为ProgrammingInS

cala这本书的节选,到目前为止,国内好像还没引进,你可以从亚马逊上面购买有国内的朋友翻译

了其中的前11 章,真是非常感谢),

  Scala是为你准备的吗?你必须自己看明白并做决定。除了伸展性之外,我们发现喜欢用

Scala编程实际上还有很多理由。最重要的四个将在本节讨论的方面该是:兼容性,简短,高层级

抽象和高级的静态类别。

 

Scala是兼容的

后退两步然后跳到Java语言前面去。它允许你在现存代码中加点

儿东西——在你已有的东西上建设——因为它被设计成无缝地与Java实施互操作。Scala程序会被

编译为JVM的字节码。它们的执行期性能通常与Java程序一致。Scala代码可以调用Java方法,

访问Java字段,继承自Java类和实现Java接口。这些都不需要特别的语法,显式接口描述,或

粘接代码。实际上,几乎所有Scala代码都极度依赖于Java库,而经常无须在程序员意识到这点。

  交互式操作的另一个方面是Scala极度重用了Java类型。Scala的Int类型代表了Java的原

始整数类型int,Float代表了float,Boolean代表boolean,等等。Scala的数组被映射到Java

数组。Scala同样重用了许多标准Java库类型。例如,Scala里的字串文本"abc"是

java.lang.String,而抛出的异常必须是java.lang.Throwable的子类。

  Scala不仅重用了Java的类型,还把它们“打扮”得更漂亮。例如,Scala的字串支持类似于

toInt和toFloat的方法,可以把字串转换成整数或者浮点数。因此你可以写str.toInt替代

Integer.parseInt(str)。如何在不打破互操作性的基础上做到这点呢?Java的String类当然不会有

toInt方法。实际上,Scala有一个解决这种高级库设计和互操作性不相和谐的通用方案。Scala可

以让你定义隐式转换:implicitconversion,这常常用在类型失配,或者选用不存在的方法时。在

上面的例子里,当在字串中寻找toInt方法时,Scala编译器会发现String类里没有这种方法,但它

会发现一个把Java的String转换为Scala的RichString类的一个实例的隐式转换,里面定义了这

么个方法。于是在执行toInt操作之前,转换被隐式应用。

  Scala代码同样可以由Java代码调用。有时这种情况要更加微妙,因为Scala是一种比Java

更丰富的语言,有些Scala更先进的特性在它们能映射到Java前需要先被编码一下。第29章说明

了其中的细节。

 

Scala是简洁的

  Scala程序一般都很短。Scala程序员曾报告说与Java比起来代码行数可以减少到1/10。这

有可能是个极限的例子。较保守的估计大概标准的Scala程序应该有Java写的同样的程序一半行

数左右。更少的行数不仅意味着更少的打字工作,同样意味着更少的话在阅读和理解程序上的努力

及更少的出错可能。许多因素在减少代码行上起了作用。

  首先,Scala的语法避免了一些束缚Java程序的固定写法。例如,Scala里的分号是可选的,

且通常不写。Scala语法里还有很多其他的地方省略了东西。比方说,比较一下你在Java和Scala

里是如何写类及构造函数的。在Java里,带有构造函数的类经常看上去是这个样子:

 

//在Java里
classMyClass{
privateintindex;
privateStringname;
publicMyClass(intindex,Stringname){
this.index=index;
this.name=name;
}
}
 

在Scala里,你会写成这样:

 

 classMyClass(index:Int,name:String)
 

  根据这段代码,Scala编译器将制造有两个私有成员变量的类,一个名为index的Int类型和一

个叫做name的String类型,还有一个用这些变量作为参数获得初始值的构造函数。这个构造函数

还将用作为参数传入的值初始化这两个成员变量。一句话,你实际拿到了与罗嗦得多的Java版本

同样的功能。Scala类写起来更快,读起来更容易,最重要的是,比Java类更不容易犯错。

  有助于Scala的简洁易懂的另一个因素是它的类型推断。重复的类型信息可以被忽略,因此程

序变得更有条理和易读。

  但或许减少代码最关键的是因为已经存在于你的库里而不需要写的代码。Scala给了你许多工

具来定义强有力的库让你抓住并提炼出通用的行为。例如,库类的不同方面可以被分成若干特质,

而这些有可以被灵活地混合在一起。或者,库方法可以用操作符参数化,从而让你有效地定义那些

你自己控制的构造。这些构造组合在一起,就能够让库的定义既是高层级的又能灵活运用。

 

Scala是高层级的

  程序员总是在和复杂性纠缠。为了高产出的编程,你必须明白你工作的代码。过度复杂的代码

成了很多软件工程崩溃的原因。不幸的是,重要的软件往往有复杂的需求。这种复杂性不可避免;

必须(由不受控)转为受控。

  Scala可以通过让你提升你设计和使用的接口的抽象级别来帮助你管理复杂性。例如,假设你

有一个String变量name,你想弄清楚是否String包含一个大写字符。在Java里,你或许这么写:

 

 

//在Java里
booleannameHasUpperCase=false;
for(inti=0;i<name.length();++i){
if(Character.isUpperCase(name.charAt(i))){
nameHasUpperCase=true;
break;
}
}
 

在Scala里,你可以写成:

valnameHasUpperCase=name.exists(_.isUpperCase)

  Java代码把字串看作循环中逐字符步进的低层级实体。Scala代码把同样的字串当作能用论断:

predicate查询的字符高层级序列。明显Scala代码更短并且——对训练有素的眼睛来说——比

Java代码更容易懂。因此Scala代码在通盘复杂度预算上能极度地变轻。它也更少给你机会犯错。

  论断,_.isUpperCase,是一个Scala里面函数式文本的例子。它描述了带一个字符参量(用

下划线字符代表)的函数,并测试其是否为大写字母。

  原则上,这种控制的抽象在Java中也是可能的。为此需要定义一个包含抽象功能的方法的接

口。例如,如果你想支持对字串的查询,就应引入一个只有一个方法hasProperty的接口

 

CharacterProperty:
//在Java里
interfaceCharacterProperty{
booleanhasProperty(charch);
}
 

  然后你可以在Java里用这个接口格式一个方法exists:它带一个字串和一个

CharacterProperty并返回真如果字串中有某个字符符合属性。然后你可以这样调用exists:

 

//在Java里
exists(name,newCharacterProperty{
booleanhasProperty(charch){
returnCharacter.isUpperCase(ch);
}
});
 

  然而,所有这些真的感觉很重。重到实际上多数Java程序员都不会惹这个麻烦。他们会宁愿

写个循环并漠视他们代码里复杂性的累加。另一方面,Scala里的函数式文本真地很轻量,于是就

频繁被使用。随着对Scala的逐步了解,你会发现越来越多定义和使用你自己的控制抽象的机会。

你将发现这能帮助避免代码重复并因此保持你的程序简短和清晰。

 

Scala是静态类型的

  静态类型系统认定变量和表达式与它们持有和计算的值的种类有关。Scala坚持作为一种具有

非常先进的静态类型系统的语言。从Java那样的内嵌类型系统起步,能够让你使用泛型:

generics参数化类型,用交集:intersection联合类型和用抽象类型:abstracttype隐藏类型的

细节。这些为建造和组织你自己的类型打下了坚实的基础,从而能够设计出即安全又能灵活使用的

接口。

  如果你喜欢动态语言如Perl,Python,Ruby或Groovy,你或许发现Scala把它的静态类型

系统列为其优点之一有些奇怪。毕竟,没有静态类型系统已被引为动态语言的某些主要长处。绝大

多数普遍的针对静态类型的论断都认为它们使得程序过度冗长,阻止程序员用他们希望的方式表达

自己,并使软件系统动态改变的某些模式成为不可能。然而,这些论断经常针对的不是静态类型的

思想,而是指责特定的那些被意识到太冗长或太不灵活的类型系统。例如,AlanKay,Smalltalk

语言的发明者,有一次评论:“我不是针对类型,而是不知道有哪个没有完痛的类型系统,所以我

还是喜欢动态类型。”

  我们希望能在书里说服你,Scala的类型系统是远谈不上会变成“完痛”。实际上,它漂亮地

说明了两个关于静态类型通常考虑的事情(的解决方案):通过类型推断避免了赘言和通过模式匹

配及一些新的编写和组织类型的办法获得了灵活性。把这些绊脚石搬掉后,静态类型系统的经典优

越性将更被赏识。其中最重要的包括程序抽象的可检验属性,安全的重构,以及更好的文档。

可检验属性:静态类型系统可以保证消除某些运行时的错误。例如,可以保证这样的属性:布尔型

不会与整数型相加;私有变量不会从类的外部被访问;函数带了正确个数的参数;只有字串可以被

加到字串集之中。

  不过当前的静态类型系统还不能查到其他类型的错误。比方说,通常查不到无法终结的函数,

数组越界,或除零错误。同样也查不到你的程序不符合式样书(假设有这么一份式样书)。静态类

型系统因此被认为不很有用而被忽视。舆论认为既然这种类型系统只能发现简单错误,而单元测试

能提供更广泛的覆盖,又为何自寻烦恼呢?我们认为这种论调不对头。尽管静态类型系统确实不能

替代单元测试,但是却能减少用来照顾那些确需测试的属性的单元测试的数量。同样,单元测试也

不能替代静态类型。总而言之,如EdsgerDijkstra所说,测试只能证明存在错误,而非不存在。因

此,静态类型能给的保证或许很简单,但它们是无论多少测试都不能给的真正的保证。

安全的重构:静态类型系统提供了让你具有高度信心改动代码基础的安全网。试想一个对方法加入

额外的参数的重构实例。在静态类型语言中,你可以完成修改,重编译你的系统并容易修改所有引

起类型错误的代码行。一旦你完成了这些,你确信已经发现了所有需要修改的地方。对其他的简单

重构,如改变方法名或把方法从一个类移到另一个,这种确信都有效。所有例子中静态类型检查会

提供足够的确认,表明新系统和旧系统可以一样的工作。

文档:静态类型是被编译器检查过正确性的程序文档。不像普通的注释,类型标注永远都不会过期

(至少如果包含它的源文件近期刚刚通过编译就不会)。更进一步说,编译器和集成开发环境可以

利用类型标注提供更好的上下文帮助。举例来说,集成开发环境可以通过判定选中表达式的静态类

型,找到类型的所有成员,并全部显示出来。

  虽然静态类型对程序文档来说通常很有用,当它们弄乱程序时,也会显得很讨厌。标准意义上

来说,有用的文档是那些程序的读者不可能很容易地从程序中自己想出来的。在如下的方法定义中:

deff(x:String)=...

  知道f的变量应该是String是有用的。另一方面,以下例子中两个标注至少有一个是讨厌的:

valx:HashMap[Int,String]=newHashMap[Int,String]()

  很明显,x是以Int为键,String为值的HashMap这句话说一遍就够了;没必要同样的句子重

复两遍。

 

  Scala有非常精于此道的类型推断系统,能让你省略几乎所有的通常被认为是讨厌的类型信息。

在上例中,以下两个不太讨厌的替代品也能一样工作:

 

valx=newHashMap[Int,String]()
valx:Map[Int,String]=newHashMap()
 

  Scala里的类型推断可以走的很远。实际上,就算用户代码丝毫没有显式类型也不稀奇。因此,

Scala编 程经常看上去有点像是动态类型脚本语言写出来的程序。尤其显著表现在作为粘接已写完

的库控件的客户应用代码上。而对库控件来说不是这么回事,因为它们常常用到相当精妙的类型去

使其适于灵活使用的模式。这很自然。综上,构成可重用控件接口的成员的类型符号应该是显式给

出的,因为它们构成了控件和它的使用者间契约的重要部分。


1
1
分享到:
评论

相关推荐

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

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

    scala和java混合编译

    它们各有特色,Java以其稳定性和广泛的社区支持而著名,Scala则以其强大的函数式编程特性及对Java虚拟机(JVM)的无缝集成受到青睐。当一个项目中同时包含Java和Scala代码时,如何有效地管理和编译这些代码就成为了...

    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 ...

    基于java、scala、python、spark实现的图书推荐系统源码+项目说明.zip

    基于java、scala、python、spark实现的图书推荐系统源码+项目说明.zip基于java、scala、python、spark实现的图书推荐系统源码+项目说明.zip基于java、scala、python、spark实现的图书推荐系统源码+项目说明.zip基于...

    面向Java开发人员的Scala指南

    为了更好地从Java过渡到Scala,开发者需要了解这些核心概念并实践编写Scala代码。《面向Java开发人员的Scala指南》这本书将深入讲解这些主题,并通过实例帮助读者理解和应用。阅读本书,Java开发者不仅可以学习到...

    Scala基础教程

    Scala在意大利语中意为“阶梯”,隐喻其提供了从Java到Scala的渐进式学习路径。 Scala的一个重要特点是它拥有简洁的代码表达能力,可以像Ruby或Python这样的动态语言一样编写,同时保持静态类型的语言特性,比如像...

    scala java相关开发工具

    标题中的“Scala Java相关开发工具”表明我们讨论的是与Java和Scala编程语言相关的开发环境和工具。Java和Scala都是在JVM(Java虚拟机)上运行的语言,它们有着紧密的联系,但各自拥有独特的特性和用途。 首先,...

    基于maven的scala与java相互调用的简单实例

    本示例着重讲解如何在Java和Scala之间进行互调用,这是基于Maven构建系统的。Maven是Apache开发的项目管理工具,它可以帮助开发者管理项目的构建、依赖关系以及文档的生成。在Java和Scala的混合开发环境中,Maven...

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

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

    基于Java、Scala和Spark的数据处理与分析设计源码

    本资源提供了一套基于Java、Scala和Spark的数据处理与分析设计源码,包含1381个文件,其中包括634个CRC文件,316个BK文件,35个Class字节码文件,20个XML配置文件,15个Java源代码文件,13个JAR打包文件,8个...

    面向Java开发人员Scala指南,Scala和servlet的比较

    这使得Java开发者可以逐步迁移到Scala,而无需完全抛弃已有的技术栈。与此同时,Scala的类型系统与Java兼容,使得Java开发者能快速上手。 对比Servlet,Scala的Web开发框架,如Play Framework,提供了更为现代的...

    scala-java8-compat_2.11-0.7.0-API文档-中英对照版.zip

    赠送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-...

    面向 Java 开发人员的 Scala 指南

    ### 面向Java开发人员的Scala指南 #### 一、引言 随着技术的不断发展,编程语言也在不断地演进。长期以来,Java作为面向对象编程的代表性语言,在软件开发领域占据主导地位。然而,近年来,一种名为Scala的新语言...

    scala-java8-compat_2.11-0.7.0-API文档-中文版.zip

    赠送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-...

    Java 和 Scala 并发性基础.doc

    Java 和 Scala 并发性基础

    Google的pagerank实现(Java+scala)Eclipse工程实例带测试数据结果和JAR包

    功能:实现google的PageRank算法,带完整的测试数据和结果,java、scala语言版本 ********************************************************* 版本: scala2.10.4 spark 1.6.1 Scala IDE Build id: 4.4.1-vfinal...

    Java电商大数据项目-推荐系统(java和scala语言)

    Java电商大数据项目-推荐系统(java和scala语言) Bump spark.version from 2.1.0 to 2.4.7 in /MySparkProject dependencies #6 by dependabot bot was merged 4 minutes ago Bump junit from 3.8.1 to 4.13.1 in /...

    基于Java、Scala、HTML的大数据领域小学生项目设计源码

    整个项目包含987个文件,具体分布如下:727个Java源文件,134个Scala源文件,54个XML文件,21个文本文件,17个属性文件,9个Markdown文件,5个Excel文件,3个备份文件,3个YAML文件,3个Protocol Buffers文件。...

    javatoscala:在线Java到Scala转换器

    Java到Scala 在线Java到Scala转换器用法克隆仓库安装sbt sbt run贡献者()问题这只是scalagen库的包装。 应当向报告错误。 库目前未维护,但是最近的分支就是。

Global site tag (gtag.js) - Google Analytics