Scala工具、库及与Java的互操作性
1. Scala命令行工具
-
scaladoc命令行工具
:scaladoc命令类似于javadoc,用于从Scala源文件生成文档(Scaladocs)。其解析器支持与javadoc相同的
@注解,如@author、@param等。使用scaladoc最简单的方法是在SBT中运行doc任务。 -
fsc命令行工具
:快速Scala编译器以守护进程方式运行,主要通过消除启动开销来实现更快的编译调用。在重复运行脚本(如反复运行测试套件直至重现某个bug)时特别有用。实际上,
scala命令会自动调用fsc,也可以直接调用它。
2. 构建工具
-
SBT(Scala标准构建工具)
- 特点 :是用于构建Scala和Java项目的强大工具,有许多配置选项和插件功能。
- 入门方法 :最快的入门方式是复制并编辑现有的构建文件,例如使用Activator Templates中的构建文件。
- 与Maven的相似性 :和Maven类似,许多常见任务(如编译和自动化测试)已内置,且任务间有合适的依赖关系(如先编译后测试)。
-
构建文件
:SBT构建由一个或多个构建文件定义。以一个简单项目为例,主构建文件
build.sbt通常位于代码示例的根目录,其内容示例如下:
name := "Programming Scala, Second Edition: Code examples"
version := "2.0"
organization := "org.programming-scala"
scalaVersion := "2.11.2"
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-actor" % "2.3.4",
"org.scalatest" %% "scalatest" % "2.2.1" % "test",
"org.scalacheck" %% "scalacheck" % "1.11.5" % "test",
...
)
scalacOptions = Seq(
"-encoding", "UTF-8", "-optimise",
"-deprecation", "-unchecked", "-feature", "-Xlint", "-Ywarn-infer-any"
)
javacOptions ++= Seq("-Xlint:unchecked", "-Xlint:deprecation")
- **控制台相关设置**:可以定义在REPL启动时自动执行的语句,例如:
initialCommands in console := """
|import foo.bar._
|import foo.bar.baz._
|""".stripMargin
还有`consoleQuick`和`consoleProject`两种控制台变体,可分别进行不同的自定义设置。
-
其他构建工具
-
Ant
:Scala发行版的
lib/scala-compiler.jar文件包含用于scalac、fsc和scaladoc的Ant任务,使用方式与相应的Java Ant任务类似。 - Maven :GitHub上有Scala Maven插件,无需安装Scala,它会自动下载。也可使用Eclipse或IntelliJ中的集成Maven支持。
- Gradle :可在Gradle上找到相关插件的详细信息。
-
Ant
:Scala发行版的
3. 与IDE和文本编辑器的集成
-
IDE集成
-
Eclipse
:可参考Scala IDE项目安装和使用Scala插件,也可下载已配置好插件的完整Eclipse包。其Scala插件有一个独特的工作表功能,结合了REPL的交互性和文本编辑器的便利性。操作步骤如下:
- 打开Scala项目,右键点击顶级项目文件夹,调用弹出菜单。
-
导航到
New → Other。 -
在“Select a wizard”对话框中,打开
Scala Wizards文件夹,选择Scala Worksheet。 -
为其命名并指定位置,文件扩展名为
.sc。
- IntelliJ IDEA :在插件偏好设置中搜索并安装Scala插件,提供与Eclipse插件类似的功能,包括自己的工作表功能。
- NetBeans :有一个Scala插件,其交互式控制台功能类似于Eclipse和IntelliJ IDEA的工作表功能。
-
Eclipse
:可参考Scala IDE项目安装和使用Scala插件,也可下载已配置好插件的完整Eclipse包。其Scala插件有一个独特的工作表功能,结合了REPL的交互性和文本编辑器的便利性。操作步骤如下:
- 文本编辑器 :许多Scala开发者喜欢使用文本编辑器,如Emacs、Vim和SublimeText。可查阅官方文档和社区论坛,为喜欢的编辑器找到可用的插件和配置选项。部分编辑器插件可使用ENSIME插件,该插件最初为Emacs设计,提供一些类似IDE的功能。
4. 测试驱动开发
- TDD概述 :测试驱动开发(TDD)是软件开发中的一种实践,先编写功能测试,再编写使测试通过的代码。
- 不同编程风格的应用差异 :TDD在面向对象程序员中更受欢迎,而函数式程序员倾向于使用REPL来确定类型和算法,之后再编写代码。不过,很多函数式程序员在编写代码后会编写一些测试,以提供回归测试套件。
-
测试工具
- ScalaTest和Specs2 :提供多种测试风格的DSL,ScalaTest可通过混入不同特质选择不同风格。
- ScalaCheck :是QuickCheck的Scala端口,ScalaTest和Specs2都可驱动ScalaCheck属性测试,且都可与JUnit和TestNG一起使用,便于混合Java和Scala测试。
5. 第三方库
-
全栈库和框架
| 名称 | URL | 描述 |
| ---- | ---- | ---- |
| Play | http://www.playframework.com/ | Typesafe支持的全栈框架,有Scala和Java API,与Akka集成 |
| Lift | http://liftweb.net/ | 最早且仍受欢迎的全栈框架 | -
后端服务库
| 名称 | URL | 描述 |
| ---- | ---- | ---- |
| Akka | http://akka.io | 全面的基于Actor的分布式计算系统 |
| Finagle | http://bit.ly/1vowyQO | 基于函数式抽象构建JVM服务的可扩展系统 |
| Unfiltered | http://bit.ly/1s0F5s3 | 用于处理HTTP请求的工具包,在各种后端服务前提供一致的API |
| Dispatch | http://bit.ly/1087FQQ | 异步HTTP的API | -
高级库
| 名称 | URL | 描述 |
| ---- | ---- | ---- |
| Scalaz | http://bit.ly/1ud2bC9 | 在Scala中开创范畴论概念的库,为许多设计问题提供实用工具 |
| Shapeless | http://bit.ly/1rGQfkG | 使用类型类和依赖类型探索泛型编程的库 | -
I/O库
| 名称 | URL | 描述 |
| ---- | ---- | ---- |
| Scala I/O | http://bit.ly/1nWmZeh | 功能齐全且受欢迎的I/O库 |
| Rapture I/O | http://rapture.io/ | 对java.io的包装,有更好的API | -
其他杂项库
| 名称 | URL | 描述 |
| ---- | ---- | ---- |
| scopt | https://github.com/scopt/scopt | 命令行解析库 |
| Typesafe Config | https://github.com/typesafehub/config | 配置库(Java API) |
| ScalaARM | http://bit.ly/13oZkdG | Joshua Suereth的自动资源管理库 |
| Typesafe Activator | https://github.com/typesafehub/activator | 管理Scala示例项目的工具 | -
Scala 2.11可选模块
| 名称 | 工件名称 | 描述 |
| ---- | ---- | ---- |
| XML | scala-xml | XML解析和构建 |
| Parser Combinators | scala-parser-combinators | 用于构建解析器的组合器库 |
| Swing | scala-swing | Swing库 |
| Async | scala-async | 为Scala提供异步编程功能,有直接操作Futures的API |
| Partest | scala-partest | Scala编译器和库的测试框架 |
| Partest Interface | scala-partest-interface | Scala编译器和库的测试框架 |
6. Scala与Java的互操作性
-
在Scala代码中使用Java名称
:Java对类型、方法、字段和变量名称的规则比Scala更严格,所以在大多数情况下,可直接在Scala代码中使用Java名称。但当Java名称是Scala关键字时,需用单反引号转义,例如
myScanner.match``。 -
Java和Scala泛型
- 在Scala中使用Java泛型 :可以在Scala代码中使用Java泛型类,如Java集合。
-
在Java中使用Scala参数化类型
:以下是一个JUnit 4测试示例,展示了在Java中使用Scala的
scala.collection.mutable.LinkedHashMap和scala.Option可能遇到的情况:
// src/test/java/progscala2/javainterop/SMapTest.java
import org.junit.*;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import static org.junit.Assert.*;
import scala.*;
import scala.collection.mutable.LinkedHashMap;
public class SMapTest extends org.scalatest.junit.JUnitSuite {
static class Name {
public String firstName;
public String lastName;
public Name(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
LinkedHashMap<Integer, Name> map;
@Before
public void setup() {
map = new LinkedHashMap<Integer, Name>();
map.update(1, new Name("Dean", "Wampler"));
}
@Test
public void usingMapGetWithOptionName() {
assertEquals(1, map.size());
Option<Name> n1 = map.get(1); // Note: Option<Name>
assertTrue(n1.isDefined());
assertEquals("Dean", n1.get().firstName);
}
@Test
public void usingMapGetWithOptionExistential() {
assertEquals(1, map.size());
Option<?> n1 = map.get(1); // Note: Option<?>
assertTrue(n1.isDefined());
assertEquals("Dean", ((Name) n1.get()).firstName);
}
}
此外,也可以在Java中使用Scala的元组类型,但无法利用Scala的语法糖。
Scala工具、库及与Java的互操作性(续)
7. 互操作性问题总结
在Scala与Java的互操作性方面,虽然整体较为无缝,但仍存在一些需要注意的细节。以下是一个简单的流程图,展示了在Scala和Java代码互调时的主要考虑点:
graph LR
A[调用方向] --> B{Scala调用Java}
A --> C{Java调用Scala}
B --> D[多数情况直接使用Java名称]
B --> E{名称为Scala关键字?}
E -->|是| F[用反引号转义]
E -->|否| D
C --> G[理解Scala特性在字节码中的编码]
C --> H[使用Scala参数化类型需注意特性]
从流程图可以看出,Scala调用Java相对简单,主要关注名称是否为Scala关键字;而Java调用Scala则需要更深入地理解Scala特性的字节码实现。
8. 综合应用示例
假设我们要开发一个简单的Web应用,结合Scala和Java的优势,使用SBT进行构建,利用ScalaTest进行测试,同时与Java代码进行互操作。以下是一个大致的操作步骤:
1.
项目初始化
- 复制一个现有的SBT构建文件,如Activator Templates中的文件,进行编辑。
- 在
build.sbt
中定义项目元数据、依赖项和编译器标志,示例如下:
name := "MyScalaJavaWebApp"
version := "1.0"
organization := "com.example"
scalaVersion := "2.11.2"
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-actor" % "2.3.4",
"org.scalatest" %% "scalatest" % "2.2.1" % "test",
"org.scalacheck" %% "scalacheck" % "1.11.5" % "test",
"com.typesafe.play" %% "play" % "2.5.10"
)
scalacOptions = Seq(
"-encoding", "UTF-8", "-optimise",
"-deprecation", "-unchecked", "-feature", "-Xlint", "-Ywarn-infer-any"
)
javacOptions ++= Seq("-Xlint:unchecked", "-Xlint:deprecation")
-
编写Scala和Java代码
- 在Scala代码中调用Java类和方法,注意处理关键字名称。
-
在Java代码中使用Scala的参数化类型,如
LinkedHashMap和Option。
-
使用IDE进行开发
- 若使用Eclipse,安装Scala插件,创建Scala项目和文件,利用工作表功能进行代码实验。
- 若使用IntelliJ IDEA,安装Scala插件,进行项目开发和测试。
-
测试驱动开发
- 使用ScalaTest和ScalaCheck编写测试用例,确保代码的正确性。
- 若项目中有Java代码,可结合JUnit和TestNG进行混合测试。
-
选择第三方库
- 根据项目需求,选择合适的第三方库,如Play框架用于构建Web应用,Akka用于分布式计算。
9. 总结与展望
通过以上介绍,我们了解了Scala的各种工具、库以及与Java的互操作性。Scala丰富的工具和强大的第三方库为开发者提供了广阔的选择空间,而与Java的无缝互操作性使得开发者可以充分利用Java生态系统的资源。在未来的开发中,随着Scala语言的不断发展和完善,相信会有更多优秀的工具和库出现,进一步提升开发效率和代码质量。同时,Scala与Java的互操作性也将更加成熟,为开发者带来更好的开发体验。
总之,Scala是一门值得深入学习和使用的语言,无论是在Web开发、分布式计算还是其他领域,都能发挥出其独特的优势。希望本文能为读者在Scala开发中提供一些帮助和启示。
超级会员免费看
170万+

被折叠的 条评论
为什么被折叠?



