Scala入门之一:Scala例子,以及如何与Java交互

转载

本文为初学Scala的Java开发者提供了一个Scala例子(Hello world),并对Scala与Java交互的情况作了一些大致的介绍。

本文源自Michel Schinz和Philipp Haller所写的A Scala Tutorial for Java programmers,由Bearice成中文。下面先对Scala进行一个简单的介绍,提供一个简单的Scala例子,并描述一下Scala与Java交互的情况。

1 简介

本文仅在对Scala语言和其编译器进行简要介绍。本文的目的读者是那些已经具有一定编程经验,而想尝试一下Scala语言的人们。要阅读本文,你应当具有基础的面向对象编程的概念,尤其是Java语言的。

2 第一个Scala例子

作为学习Scala的第一步,我们将首先写一个标准的HelloWorld,这个虽然不是很有趣,但是它可以让你对Scala有一个最直观的认识而不需要太多关于这个语言的知识。我们的Hello world看起来像这样:

1
2
3
4
5
object HelloWorld {
def main(args: Array[String]) {
println("Hello, world!")
}
}

程序的结构对Java程序员来说可能很令人怀念:它由一个main函数来接受命令行参数,也就是一个String数组。这个函数的唯一一行代码把我们的问候语传递给了一个叫println的预定义函数。main函数不返回值(所以它是一个procedure method)。所以,也不需要声明返回类型。

对于Java程序员比较陌生的是包含了main函数的object语句。这样的语句定义了一个单例对象:一个有且仅有一个实例的类。object语句在定义了一个叫HelloWorld的类的同时还定义了一个叫HelloWorld的实例。这个实例在第一次使用的时候会进行实例化。

聪明的读者可能会发现main函数并没有使用static修饰符,这是由于静态成员(方法或者变量)在Scala中并不存在。Scala从不定义静态成员,而通过定义单例object取而代之。

2.1 编译实例

我们使用Scala编译器“scalac”来编译Scala代码。和大多数编译器一样,scalac 接受源文件名和一些选项作为参数,生成一个或者多个目标文件。scala编译生成的产物就是标准的Java类文件。

假设我们吧上述代码保存为文件HelloWorld.scala,我们使用下面的命令编译它(大于号“>”表示命令提示符,你不必输入它)

可以从命令窗口运行:

1
> scalac HelloWorld.scala

这将会在当前目录生成一系列.class文件。其中的一个名为HelloWorld.class 的文件中定义了一个可以直接使用scala命令执行的类。下文中你可以看到这个例子。

2.2 运行实例

一旦完成编译,Scala程序就可以使用scala命令执行了。scala的用法和java很相似,并且连选项也大致相同。上面的例子就可以使用下面的命令运行,这将会产生我们所期望的输出。

1
2
3
>scala -classpath . HelloWorld
Hello, World!

2.3 Scala与Java交互

Scala的一个强项在于可以很简单的于已有的Java代码交互,所有java.lang中的类都已经被自动导入了,而其他的类需要显式声明导入。

来看看演示代码吧。我们希望对日期进行格式化处理,比如说用法国的格式。

Java类库定义了一系列很有用的类,比如Date和DateFormat。由于Scala于Java能够进行很好的交互,我们不需要在Scala类库中实现等效的代码,而只需直接吧Java的相关类导入就可以了:

1
2
3
4
5
6
7
8
9
10
import java.util.{Date, Locale}
import java.text.DateFormat
import java.text.DateFormat._
object FrenchDate {
def main(args: Array[String]) {
val now = new Date
val df = getDateInstance(LONG, Locale.FRANCE)
println(df format now)
}
}

Scala的import语句看上去与Java的非常相似,但是它更加强大。你可以使用大括号来导入同一个包里的多个类,就像上面代码中第一行所做的那样。另一个不同点是当导入一个包中所有的类或者符号时,你应该使用下划线(_)而不是星号(*)。这是由于星号在Scala中是一个有效的标识符(例如作为方法名称)。这个例子我们稍后会遇到。

第三行的import语句导入了DataFormat类中的所有成员,这使得静态方法getDateInstance和静态变量LONG可以被直接引用。

在main函数中,我们首先建立了一个Java的Date实例。这个实例默认会包含当前时间。接下来我们一个使用刚才导入的静态函数getDateInstance定义了日期格式。最后我们将使用DataFotmat格式化好的日期打印了出来。最后一行代码显示了Scala的一个有趣的语法:只有一个参数的函数可以使用下面这样的表达式来表示:

1
> df format now

其实就是下面的这个冗长的表达式的简洁写法

1
> df.format(now)

这看起来是一个语法细节,但是它导致一个重要的后果,我们将在下一节进行说明。

另外,我们还应当注意到Scala中可以直接继承或者实现Java中的接口和类。

看过了上面的Scala例子以及Scala与Java交互的方式,下文将介绍Scala的对象。