Java程序员的Scala教程 - 1
2012-06-20 21:17
585 查看
首先说明一下,这篇文章基本来自scala官网,说是翻译吧,也没有原本的把每句话翻下来,有些地方自己也多提了两句。顺便提一下自己工作也主要和Java打交道,废话不说了,正文如下:
官网教程: http://docs.scala-lang.org/tutorials/scala-for-java-programmers.html
习惯英文的直接上面传送。
和Java程序比较类似,他包含了一个main方法来接收命令行参数;方法调用预定义的方法println。main方法没有返回值(procedure
method 过程方法),所以也不需要对这个方法声明返回类型。
对于java程序员,有以下几点要说明:
object
object声明了这是一个单例对象(singleton
object)。它同时声明了一个名为HelloWorld的类,和一个叫做HolloWorld的实例,这个实例在第一次调用的时候创建。
static
在scala里面没有static这个概念,无论是字段还是方法。所以上面的main方法没有static关键字。所有需要声明为static的东西,都在单例对象中声明,就是上面说的object。
public
例子中main函数也没有public关键字,因为在scala中所有没有指定范围的东西(方法、成员)都默认为public的。
class文件。
比如编译上面的例子:
>
scalac
HelloWorld.scala
会在当前目录产生几个class文件,其中一个是HelloWorld.class,还包含一个可以直接被scala命令执行的class,如下节所示。
看一个简单的实例:我们希望获取当前时间并用法国风格的格式来格式输出。因为java定义了强大的类库,比如Date、DateFormat,我们不需要再引入scala中这些等价的类:
scala的import和java的差不多,但是更强大。以下需要注意:
同一个包中的不同类可在同一行引入,用大括号包起来就行了
导入包中的全部类,用_来代替java中的*,因为*在scala中是一个有效的标识符(下面会介绍)
不仅能导入类,而且能导入类中的静态方法和静态字段(都是对象啦),程序中的
getDateInstance,
LONG
分析代码第一句,创建一个
Date
实例,val是不可变对象的声明(val、var以后会讲)。然后创建一个日期格式对象,getDateInstance
是之前import的静态方法。然后打印出来,打印时用到了sacal一个有意思的语法,
表达式:
df format
now
相当于:
df.format(now)
和java交互,不仅能使用它的类,还可以直接继承一个java类、实现某个java接口。
is an
object,包括数字、方法。和java不同,java有原始类型(int、boolean、short)和引用类型,并且不能像操作值一样操作方法。
1
+
2
*
3
/
x
根据上面提到的,等价于:
(1).+(((2).*(3))./(x))
也就是说在scala里,+,*,等都是有效的标识符。
第二种写法数字两遍的小括号是必须的,因为scala对标记使用了最长匹配规则,如下:
1.+(2)
会被解释为:
1.
+
2
三部分,因为点更接近1,而1.会背认为是1.0,那样就不是一个Int了,而是当作用一个Double来计算。
(1).+(2)
上面这样写才对。
programming)
一个简单的例子来说明如何想操作值一样使用方法。考虑一个计数函数,没秒来执行一些操作。我们要如何包计数操作传递给这个计数函数呢?当然是作为一个函数了。这种简单的函数传递对很多程序员都不陌生,经常用在用户接口程序,来注册一个回调函数(当某些事件发生时触发)。
下面程序中,计数函数名为oncePerSecond,拥有一个回调函数作为参数,回调函数的类型写为()
=> Unit,这是对所有没有参数、没有返回值的函数的一种写法。
Scala中类型声明和java不一样,区别如下
Java: String name;
scala: val name: String
java: Integer getSumInteger();
scala: def getSumInteger: Integer
Unit类似与void。main函数调用计数函数,传递一个回调函数作为参数。这个程序会每个一秒println一次,一直到你电脑关机(如果不结束程序)。
4.3匿名函数
上面例子定义的timeFiles函数,只被用到了一次,定义出来有点浪费,在scala中完全可以用匿名函数代替。改写后如下:
匿名函数用=>来区分函数的参数列表和函数体。当然这个匿名函数的没有参数,也就是一个(),在=>的左边,右边就是函数体,只有一句话。
class
Complex(real: Double, imaginary: Double) {
def
re() = real
def
im() = imaginary
}
这个类包含了两个参数,两个方法。生成实例时必须要包含这两个参数:
new
Complex(1.5, 2.3)
注意上面两个方法都没有标明返回值,scala编译器会根据函数体自动推断(例子中为Double)。默认会在函数体的最后一句话前加上一个return,这点以后开单张讲解。
5.1无参方法
一个小问题:当调用方法时必须加上一个小括号(方法没有参数时):
object
ComplexNumbers {
def
main(args: Array[String]) {
val
c = new
Complex(1.2, 3.4)
println("imaginary
part: " + c.im())
}
}
在scala中,对于0参数的方法,无论定义或者调用都可以把小括号省略,如下:
class
Complex(real: Double, imaginary: Double) {
def
re = real
def
im = imaginary
}
5.2继承和重写
Scala中的任何类都集成自父类,如果没有声明父类(上面例子),会隐含集成scala.AnyRef类。
重写父类方法必许使用override关键字修饰:
class
Complex(real: Double, imaginary: Double) {
def
re = real
def
im = imaginary
overridedef
toString() =
""
+ re + (if
(im < 0) ""else"+")
+ im + "i"
}
今天到这里,明天明天继续。
官网教程: http://docs.scala-lang.org/tutorials/scala-for-java-programmers.html
习惯英文的直接上面传送。
1Introduce
对scala语言和编译进行一个简单的介绍。2A First Example
第一个程序还用标准的 Hello World 来做例子。objectHelloWorld{ def main(args:Array[String]){ println("Hello, world!") } }
和Java程序比较类似,他包含了一个main方法来接收命令行参数;方法调用预定义的方法println。main方法没有返回值(procedure
method 过程方法),所以也不需要对这个方法声明返回类型。
对于java程序员,有以下几点要说明:
object
object声明了这是一个单例对象(singleton
object)。它同时声明了一个名为HelloWorld的类,和一个叫做HolloWorld的实例,这个实例在第一次调用的时候创建。
static
在scala里面没有static这个概念,无论是字段还是方法。所以上面的main方法没有static关键字。所有需要声明为static的东西,都在单例对象中声明,就是上面说的object。
public
例子中main函数也没有public关键字,因为在scala中所有没有指定范围的东西(方法、成员)都默认为public的。
2.1Compiling the example
用scalac这个scala的编译器来编译上面程序。和大部分的编译器一样,运行它需要一个文件名,也可以加上其他的选项,然后产生一个或多个对象文件。Scalac生成的对象文件是标准的Javaclass文件。
比如编译上面的例子:
>
scalac
HelloWorld.scala
会在当前目录产生几个class文件,其中一个是HelloWorld.class,还包含一个可以直接被scala命令执行的class,如下节所示。
2.2Running the example
编译好,就可以用scala命令运行了,类似java命令:>
scala
-
classpath
.
HelloWorld
> Hello
,
world
!
3Interaction with Java
Scala可以很简单的和Java代码交互。Java.lang包中的所有类都会被scala默认导入,而其他的java类就需要自己明确的导入了。看一个简单的实例:我们希望获取当前时间并用法国风格的格式来格式输出。因为java定义了强大的类库,比如Date、DateFormat,我们不需要再引入scala中这些等价的类:
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的差不多,但是更强大。以下需要注意:
同一个包中的不同类可在同一行引入,用大括号包起来就行了
导入包中的全部类,用_来代替java中的*,因为*在scala中是一个有效的标识符(下面会介绍)
不仅能导入类,而且能导入类中的静态方法和静态字段(都是对象啦),程序中的
getDateInstance,
LONG
分析代码第一句,创建一个
Date
实例,val是不可变对象的声明(val、var以后会讲)。然后创建一个日期格式对象,getDateInstance
是之前import的静态方法。然后打印出来,打印时用到了sacal一个有意思的语法,
表达式:
df format
now
相当于:
df.format(now)
和java交互,不仅能使用它的类,还可以直接继承一个java类、实现某个java接口。
4Everything is an Object
Scala是纯面向对象的语言,everythingis an
object,包括数字、方法。和java不同,java有原始类型(int、boolean、short)和引用类型,并且不能像操作值一样操作方法。
4.1数字是对象
数字是对象,那么当然应该有方法了,其实常用的操作符就是啦:1
+
2
*
3
/
x
根据上面提到的,等价于:
(1).+(((2).*(3))./(x))
也就是说在scala里,+,*,等都是有效的标识符。
第二种写法数字两遍的小括号是必须的,因为scala对标记使用了最长匹配规则,如下:
1.+(2)
会被解释为:
1.
+
2
三部分,因为点更接近1,而1.会背认为是1.0,那样就不是一个Int了,而是当作用一个Double来计算。
(1).+(2)
上面这样写才对。
4.2方法是对象
这可能让Java程序员感到更加惊奇,在scala中方法也是对象。可以把方法当作参数来传递,存储在一个变量里,作为返回值。这种操作函数的能力称为函数式编程。(函数式编程有很多探讨,可以google: functionalprogramming)
一个简单的例子来说明如何想操作值一样使用方法。考虑一个计数函数,没秒来执行一些操作。我们要如何包计数操作传递给这个计数函数呢?当然是作为一个函数了。这种简单的函数传递对很多程序员都不陌生,经常用在用户接口程序,来注册一个回调函数(当某些事件发生时触发)。
下面程序中,计数函数名为oncePerSecond,拥有一个回调函数作为参数,回调函数的类型写为()
=> Unit,这是对所有没有参数、没有返回值的函数的一种写法。
Scala中类型声明和java不一样,区别如下
Java: String name;
scala: val name: String
java: Integer getSumInteger();
scala: def getSumInteger: Integer
Unit类似与void。main函数调用计数函数,传递一个回调函数作为参数。这个程序会每个一秒println一次,一直到你电脑关机(如果不结束程序)。
object Timer { def oncePerSecond(callback: () => Unit) { while (true) { callback(); Thread sleep 1000 } } def timeFlies() { println("time flies like an arrow...") } def main(args: Array[String]) { oncePerSecond(timeFlies) } }
4.3匿名函数
Anonymous functions
上面例子定义的timeFiles函数,只被用到了一次,定义出来有点浪费,在scala中完全可以用匿名函数代替。改写后如下:object TimerAnonymous { def oncePerSecond(callback: () => Unit) { while (true) { callback(); Thread sleep 1000 } } def main(args: Array[String]) { oncePerSecond(() => println("time flies like an arrow...")) } }
匿名函数用=>来区分函数的参数列表和函数体。当然这个匿名函数的没有参数,也就是一个(),在=>的左边,右边就是函数体,只有一句话。
5Classes
scala中的class定义和java差不多,而且增加了类参数:class
Complex(real: Double, imaginary: Double) {
def
re() = real
def
im() = imaginary
}
这个类包含了两个参数,两个方法。生成实例时必须要包含这两个参数:
new
Complex(1.5, 2.3)
注意上面两个方法都没有标明返回值,scala编译器会根据函数体自动推断(例子中为Double)。默认会在函数体的最后一句话前加上一个return,这点以后开单张讲解。
5.1无参方法
Methods without arguments
一个小问题:当调用方法时必须加上一个小括号(方法没有参数时):object
ComplexNumbers {
def
main(args: Array[String]) {
val
c = new
Complex(1.2, 3.4)
println("imaginary
part: " + c.im())
}
}
在scala中,对于0参数的方法,无论定义或者调用都可以把小括号省略,如下:
class
Complex(real: Double, imaginary: Double) {
def
re = real
def
im = imaginary
}
5.2继承和重写
Inheritance and overriding
Scala中的任何类都集成自父类,如果没有声明父类(上面例子),会隐含集成scala.AnyRef类。重写父类方法必许使用override关键字修饰:
class
Complex(real: Double, imaginary: Double) {
def
re = real
def
im = imaginary
overridedef
toString() =
""
+ re + (if
(im < 0) ""else"+")
+ im + "i"
}
今天到这里,明天明天继续。
相关文章推荐
- 为Java程序员编写的Scala的入门教程
- 为Java程序员编写的Scala的入门教程
- 为Java程序员编写的Scala的入门教程
- Java程序员的Scala的入门教程
- Java程序员的Scala入门教程
- 写给Java程序员的Scala入门教程
- 写给 Java 程序员的 Scala 教程
- java视频教程之十个程序员要知道的调试技巧
- 云星数据---Scala实战系列(精品版)】:Scala入门教程016-Scala实战源码-Scala 判断语句 、循环与java的比较
- 给Java开发者的Scala教程
- 教程 | 写给Python程序员的Scala入门教程
- 写给Python程序员的Scala入门教程
- Java程序员的C#入门教程 - 开发环境搭建
- 当java程序员遇到微信跳一跳会擦出什么火花?(详细教程)
- java程序员学习scala前必看的技术文档(1)
- java教程Java系统程序员修炼之道
- Java Android程序员软件开发知识:枚举的介绍,以及代码的编写教程。
- Java手机游戏开发简明教程 (SunJava开发者认证程序员 郎锐)
- 给Java开发者的Scala教程
- 给Java开发者的Scala教程