A Scala Tutorial
for Java programmers
Version1.3atelier
March15,2009
Michel Schinz,Philipp
Haller
靳雄飞(中文翻译)
P ROGRAMMING M ETHODS L ABORATORY
EPFL
S WITZERLAND
1 介绍- Introduction
本文档是Scala语言和编译器的快速入门介绍,适合已经有一定编程经验,且希望了解Scala可以做什么的读者。我们假定本文的读者具有面向对象编程(Object-oriented programming,尤其是java相关)的基础知识。
This document gives a quick introduction to the Scala language and compiler. It
is intended for people who already have some programming experience and want
an overview of what they can do with Scala. A basic knowledge of object-oriented programming, especially in Java, is assumed.
2 第一个例子-A first example在线互译
我们使用最经典的“Hello world”作为第一个例子,这个例子虽然并不是特别炫(fascinating),但它可以很好的展示Scala的用法,且无须涉及太多的语言特性。示例代码如下:
As a first example, we will u the standard Hello world program. It is not very fascinatingbut makes it easy to demonstrate the u of the Scala tools without knowing too much about the language. Here is how it looks:
object HelloWorld { def
main(args: Array[String])
{ println("Hello,
world!") } }
Java程序员应该对示例代码的结构感到很熟悉:它包含一个main方法,其参数是一个字符串数组,用来接收命令行参数;main的方法体只有一句话,调用预定义的println 方法输出“Hello world!”问候语。main方法不返回值(这是一个过程方法procedure method),因此,该方法不必声明返回值类型。
The structure of this program should be familiar to Java programmers: it consists of one method called main which takes the command line arguments, an array of strings, as parameter; the body of this method consists of a single call to the predefined method println with the friendly greeting as argument. The main method does not return a value (it is a procedure method). Therefore, it is not necessary to declare a return type.
对于包含main方法的object声明,Java程序员可能要相对陌生一些。这种声明方式引入了一个通常被称为单例对象(singleton object)的概念,也就是有且仅有一个实例的类。因此,上例中的声明,在
定义了一个名为的HelloWorld类的同时,还声明了该类的一个实例,实例的名字也叫HelloWorld。该实例在第一次被用到的时候即时(on demand)创建。
What is less familiar to Java programmers is the object declaration containing the main method. Such a declaration introduces what is commonly known as a singleton object, that is a class with a single instance. The declaration above thus declares both
a class called HelloWorld and an instance of that class, also called HelloWorld. This instance is created on demand, the first time it is ud.
细心(astute,机敏的,聪明的)的读者可能会注意到,main方法并没有声明为static。这是因为Scala中不存在静态成员(无论方法还是属性,methods or fields)这一概念,Scala使用前述的单例对象(singleton objects)中的成员来代替静态成员。
武汉室内设计培训The astute reader might have noticed that the main method is not declared as static here. This is becau static members (methods or fields) do not exist in Scala. Rather than defining static members, the Scala programmer declares the members in singleton objects.
2.1 编译该示例- Compiling the example
要编译上面写的例子,要scalac命令,这就是Scala的编译器。scalac的工作流程和多数编译器类似:从命令行上接收待编译的源文件名(source file)以及编译参数,生成一个或者多个目标文件(object files,或者叫对象文件)。Scala生成的目标文件是标准的java class文件。
To compile the example, we u scalac, the Scala compiler. scalac works like most compilers: it takes a source file as argument, maybe some options, and produces one or veral object files. The object files it produces are standard Java class files.
假如我们将HelloWorld示例程序存放到HelloWorld.scala文件中,则可以用以下指令进行编译(大于号’>’表示shell/命令行的提示符,不需要人工键入):
If we save the above program in a file called HelloWorld.scala, we can compile it by issuing the following command (the greater-than sign ‘>’ reprents the shell prompt and should not be typed):
> scalac HelloWorld.scala
该指令执行后,会在当前目录下生成几个class文件,其中一个是HelloWorld.class,该文件中包含一个可以直接被scala指令执行的类(class),具体操作参见后续章节。This will generate a few class files in the current directory. One of them will be called HelloWorld.class, and contains a class which can be directly executed using the scala command, as the following ction shows.
2.2 运行该示例-Running the example
代码编译通过以后,可以使用scala指令运行程序,scala指令和java指令的用法非常相似,甚至它们接受的命令行参数都是一样的。前面编译好的例子,可以用如下指令运行,并输出预期的问候语:
Once compiled, a Scala program can be run using the scala command. Its usage is very similar to the java command ud to run Java programs, and accepts the same options. The above example can be executed using the following command, which produces the expected output:
> scala -classpath . HelloWorld
Hello, world!
3 和Java进行交互- Interaction with Java
和Java代码的交互能力,是Scala语言的强项之一。在Scala程序中,java.lang包下的类是默认全部引入的,其它包下的类则需要显式(explicitly)引入。
One of Scala’s strengths is that it makes it very easy to interact with Java code. All class from the java.lang package are imported by default, while others need to be imported explicitly.
我们可以通过一个例子来展示Scala与Java的交互能力。假如,我们想获取系统当前时间,并按照某个国家(比如法国)的显示习惯进行格式化1。
Let’s look at an example that demonstrates this. We want to obtain and format the current date according to the conventions ud in a specific country, say France1.
我们知道,在Java的类库中已经实现了Date、DateFormat等功能强大的工具类,且Scala可以和Java进行无缝(emlessly)的互操作,所以,想在Scala程序中使用这些功能,只需要引入这些Java类即可,无须从头重复实现相同的功能。
Java’s class libraries define powerful utility class, such as Date and DateFormat. Since Scala interoperates emlessly with Java, there is no need to implement equivalent class in the Scala class library–we can simply import the class of the corresponding Java packages:
import java.util.{Date, Locale}
DateFormat
DateFormat._
rolesobject FrenchDate {
def main(args: Array[String]) {
val now = new Date
val df = getDateInstance(LONG, Locale.FRANCE)
println(df format now)
}
}
Scala的import语句和Java中的import很想象,但Scala的语法更强大一些。比如,
要想引入一个包中的多个类,在Scala中可以写在一行上,只需要把多个类名放到
data是什么意思
一个大括号中(curly braces, {})即可。此外,如果要引入一个包或者类中的所有名字,Scala使用下划线(underscore,_)而不是星号(asterisk,*),这是因为,在Scala 中,星号是一个合法的标识符(比如:方法名),后面我们会遇到这种情况。
1其它说法语的国家和地区,比如瑞士的部分地区通常也使用相同的格式。
Scala’s import statement looks very similar to Java’s equivalent, however, it is more powerful. Multiple class can be imported from the same package by enclosing them in curly braces as on the first line. Another difference is that when importing all the names of a package or class, one us the underscore character (_) instead of the asterisk (*). That’s becau the asterisk is a valid Scala identifier (e.g. method name), as we will e later.
el dorado因此,上例中第三行的import语句,引入了DateFormat类的所有成员,这样该类的静态方法getDateInstance和静态属性LONG对FrenchDate类来说,是直接可见的(directly visible)。
The import statement on the third line therefore imports all members of the DateFormat class. This makes the static method getDateInstance and the static field LONG directly visible.
在main方法中,我们首先创建一个Java的Date实例,该实例默认取得系统当前时间;接下来,我们使用从DateFormat类中引入的静态方法getDateInstance创建一
个负责日期格式化的对象df,创建过程中,通过参数指定了本地化区域(Locale.FRANCE);最后,使用df将当前时间进行格式化并打印输出到控制台。
这个方法的最后一行,体现了Scala语法中一种很有意思的特性(interesting property):如果一个方法只接受一个参数,那么可以使用infix语法,也就是说,
reprentation
下面的表达式:
antiphishingdf format now
存在即合理英文和df.format(now)的语义完全相同,只是前者更加简洁。
Inside the main method we first create an instance of Java’s Date class which by default contains the current date. Next, we define a date format using the static getDateInstance method that we imported previously. Finally, we print the current date formatted according to the localized DateFormat instance. This last line shows an interesting property of Scala’s syntax. Methods taking one argument can be ud with an infix syntax. That is, the expression
nagisadf format now
is just another, slightly less verbo way of writing the expression
df.format(now)
这虽然是一个很小的语法细节,但它具有深远的影响,本文后续的章节中将会有进
一步的论述。
This might em like a minor syntactic detail, but it has important conquences, one of which will be explored in the next ction.
最后,从Java与Scala整合的角度看,值得一提的是,Scala中可以直接继承Java
的类或者实现Java的接口。