Skip to content

Commit 8d75c85

Browse files
committed
Update Translation
1 parent 3281ca0 commit 8d75c85

File tree

1 file changed

+27
-27
lines changed

1 file changed

+27
-27
lines changed

zh-cn/tutorials/scala-for-java-programmers.md

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,29 +13,29 @@ Lightsing 译
1313

1414
## 介绍
1515

16-
此教学将对 Scala 语言以及编译器做一个简易介绍。面向的读者为具有变成经验且想简要了解 Scala 的人。本文假设读者有着基本、特别是 Java 上的面向对象知识。
16+
此教学将对 Scala 语言以及编译器做一个简易介绍。面向的读者为具有编程经验,并且想简单了解 Scala 的人。本文假设读者有着基本的、最好是 Java 上的面向对象知识。
1717

1818
## 第一个例子
1919

20-
这里用标准的 *Hello world* 程序作为第一个例子。虽然它很无趣,可是这让我们在仅用少量语言特性下演示 Scala 工具。程序如下:
20+
这里用标准的 *Hello world* 程序作为第一个例子。虽然它很无趣,但让我们可以用少量语言特质来演示 Scala 工具。程序如下:
2121

2222
object HelloWorld {
2323
def main(args: Array[String]) {
2424
println("Hello, world!")
2525
}
2626
}
2727

28-
Java 程序员应该对这个程序结构感到熟悉:这有一个`main` 函数,该函数接受一个字符串阵列参数,也就是命令列参数;函数内容为调用已定义好的函数`println ` 并用Hello world 字符串当参数。 `main` 函数没有回传值 (它是程序函数)。因此并不需要声明回传类型
28+
Java 程序员应该对这个程序结构感到熟悉:这有一个`main` 函数,该函数接受一个字符串数组作为参数,即命令行参数;函数内容为调用已定义好的函数`println ` 并用Hello world 字符串当参数。 `main` 函数没有返回值 (它是一个过程方法)。因此并不需要声明返回值类型
2929

30-
Java 程序员不太熟悉的是包着 `main` 函数的 `object` 声明。这种声明引入我们一般称之 *Singleton* 的东西,也就是只有一个实例的类。所以上面的声明同时声明了一个 `HelloWorld` 类跟一个这类的实例,也叫做 `HelloWorld`。该实例会在第一次被使用到的时候即时产生。
30+
Java 程序员不太熟悉的是包着 `main` 函数的 `object` 声明。这种声明引入我们一般称之 *Singleton* 的东西,也就是只有一个实例的类。所以上面的代码同时声明了一个 `HelloWorld` 类和一个这类的实例,也叫做 `HelloWorld`。该实例会在第一次被使用到的时候即时产生。
3131

3232
眼尖的读者可能已经注意到这边 `main` 函数的声明没有带着 `static`。这是因为 Scala 没有静态成员 (函数或属性)。 Scala 程序员将这成员声明在单实例对象中,而不是定义静态成员。
3333

34-
### 编译这例子
34+
### 编译这个例子
3535

3636
我们用 Scala 编译器 `scalac`来编译这个例子。 `scalac` 就像大多数编译器一样,它接受源代码文件当对象,并接受额外的选项,然后产生一个或多个对象文件。它产出的对象文件为标准 Java class 文件。
3737

38-
如果我们将上面的程序存成 `HelloWorld.scala` 档,编译指令为( `>` 是提示字符,不用打):
38+
如果我们将上面的程序存为文件 `HelloWorld.scala` 档,编译指令为( `>` 是提示字符,不用打):
3939

4040
> scalac HelloWorld.scala
4141

@@ -51,7 +51,7 @@ Java 程序员不太熟悉的是包着 `main` 函数的 `object` 声明。这种
5151

5252
## 与 Java 互动
5353

54-
Scala 的优点之一是它非常容易跟 Java 代码沟通。预设导入了所有 `java.lang` 底下之类,其他类则需要明确导入。
54+
Scala 的优点之一是它非常容易跟 Java 代码沟通。Scala 会默认 import `java.lang` 底下之类,其他类则需要明确导入。
5555

5656
让我们看个展示这点的示例。取得当下日期并根据某个特定国家调整成该国格式,如法国。
5757

@@ -73,15 +73,15 @@ Scala 的导入表达式跟 Java 非常像,但更为强大。如第一行,
7373

7474
所以第三行的表达式导入所有 `DateFormat` 类的成员。这让静态方法 `getDateInstance` 跟静态属性 `LONG` 可直接被使用。
7575

76-
`main` 函数中我们先创造一个 Java 的 `Date` 类实例,该实例预设拥有现在的日期。接下来用 `getDateInstance` 函数定义日期格式。最后根据地区化的 `DateFormat` 实例对现在日期设定格式并印出。最后一行展现了一个 Scala 有趣特点。只需要一个对象的函数可以用中缀语法调用。就是说,这个表达式
76+
`main` 函数中我们先创造一个 Java 的 `Date` 类实例,该实例默认拥有现在的日期。接下来用 `getDateInstance` 函数定义日期格式。最后根据地区化的 `DateFormat` 实例对现在日期设定格式并印出。最后一行展现了一个 Scala 有趣特点。只需要一个对象的函数可以用中缀语法调用。就是说,这个表达式
7777

7878
df format now
7979

8080
是这个表达式的简略版本
8181

8282
df.format(now)
8383

84-
这点也许看起来只是语法上的小细节,但是它有着重要的后果,其中一个将会在下一节做介绍
84+
它看起来也许只是语法上的小细节,但却有着重要的影响,其中一个影响将会在下一节做介绍
8585

8686
最后值得一提的是,Scala 可以直接继承 Java 类或者实现 Java 接口。
8787

@@ -115,9 +115,9 @@ Scala 是一个纯粹的面向对象语言,这句话的意思是说,*所有
115115

116116
可能令 Java 程序员更为惊讶的会是,Scala 中函数也是对象。因此,将函数当做对象传递、把它们存入变量、从其他函数返回函数都是可能的。能够像操作变量一样的操作函数这点是*函数式编程*这一非常有趣的程序设计思想的基石之一。
117117

118-
为何把函数当做变量一样的操作会很有用呢,让我们考虑一个定时函数,功能是每秒执行一些动作。我们要怎么将这动作传给它?最直接的便是将这动作视为函数传入。应该有不少程序员对这种简单传递函数的行为很熟悉:通常在使用者介面相关的程序上,用以注册一些当事件发生时被调用的回呼函数
118+
为何把函数当做变量一样的操作会很有用呢,让我们考虑一个定时函数,功能是每秒执行一些动作。我们要怎么将这动作传给它?最直接的便是将这动作视为函数传入。应该有不少程序员对这种简单传递函数的行为很熟悉:通常在用户界面相关的程序上,用来注册一些当事件发生时被调用的回调函数
119119

120-
在接下来的程序中,定时函数叫做 `oncePerSecond`它接受一个回呼函数做参数。该函数的类型被写作 `() => Unit` ,这个类型便是所有无对象且无返回值函数的类型( `Unit` 这个类型就像是 C/C++ 的 `void` )。此程序的主函数只是调用定时函数并带入回呼函数,回呼函数输出一句话到终端上。也就是说这个程序会不断的每秒输出一次 "time flies like an arrow"。
120+
在接下来的程序中,定时函数叫做 `oncePerSecond`它接受一个回调函数做参数。该函数的类型被写作 `() => Unit` ,这个类型便是所有无对象且无返回值函数的类型( `Unit` 这个类型就像是 C/C++ 的 `void` )。此程序的主函数只是调用定时函数并带入回呼函数,回呼函数输出一句话到终端上。也就是说这个程序会不断的每秒输出一次 "time flies like an arrow"。
121121

122122
object Timer {
123123
def oncePerSecond(callback: () => Unit) {
@@ -131,7 +131,7 @@ Scala 是一个纯粹的面向对象语言,这句话的意思是说,*所有
131131
}
132132
}
133133

134-
值得注意的是,这边输出时我们使用 Scala 的函数 `println`,而不是 `System.out` 里的函数
134+
值得注意的是,在打印字符串时,我们使用的是 Scala 预定义的方法 `println`,而不是 `System.out` 中的
135135

136136
#### 匿名函数
137137

@@ -151,7 +151,7 @@ Scala 是一个纯粹的面向对象语言,这句话的意思是说,*所有
151151

152152
##
153153

154-
之前已讲过,Scala 是一个面向对象语言,因此它有着类的概念 (更精确的说,的确有一些面向对象语言没有类的概念,但是 Scala 不是这种)。Scala 声明类的语法跟 Java 很接近。一个重要的差别是,Scala 的类可以有参数。这边用底下复数的定义来展示
154+
之前已讲过,Scala 是一个面向对象语言,因此它有着类的概念 (更精确的说,的确有一些面向对象语言没有类的概念,但是 Scala 不是其中之一)。Scala 声明类的语法跟 Java 很接近。一个重要的差别是,Scala 的类可以有参数。如下面展示的复数的定义
155155

156156
class Complex(real: Double, imaginary: Double) {
157157
def re() = real
@@ -162,7 +162,7 @@ Scala 是一个纯粹的面向对象语言,这句话的意思是说,*所有
162162

163163
值得注意的是,这两个函数的回传值并没有被明确给定。编译器将会自动的推断,它会查看这些函数的右侧并推导出这两个函数都会回传类型为 `Double` 的值。
164164

165-
编译器并不一定每次都能够推断出类型,而且很不幸的是我们并没有简单规则以分辨哪种情况能推断,哪种情况不能。因为当编译器无法推断未明确给定的类型时它会回报错误,实务上这通常不是问题。Scala 初学者在遇到那些看起来很简单就能推导出类型的情况时,应该尝试着忽略类型声明并看看编译器是不是也觉得可以推断。多尝试几次之后程序员应该能够体会到何时忽略类型、何时该明确指定。
165+
编译器并不一定每次都能够推断出类型,而且很不幸的是我们并没有简单规则以分辨哪种情况能推断,哪种情况不能。实践上这通常不是问题,因为当编译器无法推断未明确给定的类型时,它会报错。Scala 初学者在遇到那些看起来很简单就能推导出类型的情况时,应该尝试着忽略类型声明并看看编译器是不是也觉得可以推断。多尝试几次之后程序员应该能够体会到何时忽略类型、何时该明确指定。
166166

167167
### 无对象函数
168168

@@ -248,11 +248,11 @@ Java 中我们会将这个树用一个抽象父类表示,然后每种节点跟
248248
3. 如果第二个检查也失败,表示树不是 `Sum` 也不是 `Var`,那便检查是不是 `Const`,如果是的话将 `Const` 所带的名称绑定到变量 `v` 并求值右侧表达式,
249249
4. 最后,如果全部检查都失败,会抛出异常表示匹配失败;这只会在有更多 `Tree` 的子类时发生。
250250

251-
如上,模式匹配基本上就是尝试将一个值对一系列模式做匹配,并在一个模式成功匹配时抽取并命名该值的各部分,最后对一些代码求值,而这些代码通常会利用被命名到的部位
251+
如上,模式匹配基本上就是尝试将一个值对一系列模式做匹配,并在一个模式成功匹配时抽取并命名该值的各部分,最后对一些代码求值,而这些代码通常会利用被命名到的部分
252252

253253
一个经验丰富的面向对象程序员也许会疑惑为何我们不将 `eval` 定义成 `Tree` 类跟子类的*方法*。由于 Scala 允许在 case class 中跟一般类一样定义函数,事实上我们可以这样做。要用模式匹配或是函数只是品味的问题,但是这会对扩充性有重要影响。
254254

255-
- 当使用函数时,只要定义新的 `Tree` 子类便新增新节点,相当容易。另一方面,增加新操作需要修改所有子类,很麻烦
255+
- 当使用函数时,增加新的节点类型是相当容易的,只要定义新的 `Tree` 子类即可。不过另一方面,为树增加新操作很麻烦,因为它需要修改 `Tree` 的所有子类
256256
- 当使用模式匹配时情况则反过来:增加新节点需要修改所有对树做模式匹配的函数将新节点纳入考虑;增加新操作则很简单,定义新函数就好。
257257

258258
让我们定义新操作以更进一步的探讨模式匹配:对符号求导数。读者们可能还记得这个操作的规则:
@@ -291,17 +291,17 @@ Java 中我们会将这个树用一个抽象父类表示,然后每种节点跟
291291
Derivative relative to y:
292292
Sum(Sum(Const(0),Const(0)),Sum(Const(0),Const(1)))
293293

294-
研究这输出我们可以发现,取导数的结果应该在输出前更进一步化简。用模式匹配实作一个基本化简函数是一个很有趣 (但是意外的棘手) 的问题,在这边留给读者当练习。
294+
研究这输出我们可以发现,取导数的结果应该在输出前更进一步化简。用用模式匹配实现一个基本化简函数是一个很有趣 (但是意外的棘手) 的问题,在这边留给读者当练习。
295295

296-
## 特性 (Traits)
296+
## 特质 (Traits)
297297

298-
除了由父类继承行为以外,Scala 类还可以从一或多个*特性*导入行为。
298+
除了由父类继承行为以外,Scala 类还可以从一或多个*特质*导入行为。
299299

300-
对一个 Java 程序员最简单去理解特性的方式应该是视它们为带有实例的接口。在 Scala 里,当一个类继承特性时,它实作了该特性的介面并继承所有特性带有的功能
300+
对一个 Java 程序员最简单去理解特质的方式应该是视它们为带有实例的接口。在 Scala 里,当一个类继承特质时,它实现了该特质的接口并继承所有特质带有的功能
301301

302-
为了理解特性的用处,让我们看一个经典示例:有序对象。大部分情况下,一个类所产生出来的对象之间可以互相比较大小是很有用的,如排序它们。在Java里可比较大小的对象实作 `Comparable` 介面。在Scala中借由定义等价于 `Comparable` 的特性 `Ord`,我们可以做的比Java稍微好一点。
302+
为了理解特质的用处,让我们看一个经典示例:有序对象。大部分情况下,一个类所产生出来的对象之间可以互相比较大小是很有用的,如排序它们。在Java里可比较大小的对象实作 `Comparable` 介面。在Scala中借由定义等价于 `Comparable` 的特质 `Ord`,我们可以做的比Java稍微好一点。
303303

304-
当在比较对象的大小时,有六个有用且不同的谓词 (predicate):小于、小于等于、等于、不等于、大于等于、大于。但是把六个全部都实现很烦,尤其是当其中有四个可以用剩下两个表示的时候。也就是说,(举例来说) 只要有等于跟小于谓词,我们就可以表示其他四个。在 Scala 中这些观察可以很漂亮的用下面的特性声明呈现
304+
当在比较对象的大小时,有六个有用且不同的谓词 (predicate):小于、小于等于、等于、不等于、大于等于、大于。但是把六个全部都实现很烦,尤其是当其中有四个可以用剩下两个表示的时候。也就是说,(举例来说) 只要有等于跟小于谓词,我们就可以表示其他四个。在 Scala 中这些观察可以很漂亮的用下面的特质声明呈现
305305

306306
trait Ord {
307307
def < (that: Any): Boolean
@@ -322,7 +322,7 @@ Java 中我们会将这个树用一个抽象父类表示,然后每种节点跟
322322
def day = d
323323
override def toString(): String = year + "-" + month + "-" + day
324324

325-
这边要注意的是声明在类名称跟参数之后的 `extends Ord`。这个语法声明了 `Date` 继承 `Ord` 特性
325+
这边要注意的是声明在类名称跟参数之后的 `extends Ord`。这个语法声明了 `Date` 继承 `Ord` 特质
326326

327327
然后我们重新定义继承自 `Object``equals` 函数好让这个类可以正确的根据每个属性来比较日期。因为在 Java 中 `equals` 直接比较实际对象本身,并不能在这边用。于是我们有下面的例子:
328328

@@ -346,19 +346,19 @@ Java 中我们会将这个树用一个抽象父类表示,然后每种节点跟
346346
(month == o.month && day < o.day)))
347347
}
348348

349-
这边使用了另外一个预定义函数 `error`,它会丢出带着给定错误信息的例外。这便完成了 `Date` 类。这个类的实例可被视为日期或是可比较对象。而且它们通通都定义了之前所提到的六个比较谓词: `equals``<` 直接出现在类定义当中,其他则是继承自 `Ord` 特性
349+
这边使用了另外一个预定义函数 `error`,它会丢出带着给定错误信息的例外。这便完成了 `Date` 类。这个类的实例可被视为日期或是可比较对象。而且它们通通都定义了之前所提到的六个比较谓词: `equals``<` 直接出现在类定义当中,其他则是继承自 `Ord` 特质
350350

351-
特性在其他场合也有用,不过详细探讨它们的用途并不在本文件目标内。
351+
特质在其他场合也有用,不过详细探讨它们的用途并不在本文件目标内。
352352

353353
## 泛型
354354

355-
在这份教学里,我们最后要探讨的 Scala 特性是泛型。Java 程序员应该相当清楚在 Java 1.5 之前缺乏泛型所导致的问题。
355+
在这份教学里,我们最后要探讨的 Scala 特质是泛型。Java 程序员应该相当清楚在 Java 1.5 之前缺乏泛型所导致的问题。
356356

357357
泛型指的是能够将类型也作为程序参数。举例来说,当程序员在为链表写函数库时,它必须决定列表的元素类型为何。由于这列表是要在许多不同场合使用,不可能决定列表的元素类型为如 `Int` 一类。这样限制太多。
358358

359359
Java 程序员采用所有对象的父类 `Object`。这个解决办法并不理想,一方面这并不能用在基础类型 (`int``long``float` 之类),再来这表示必须靠程序员手动加入大量的动态转型。
360360

361-
Scala 借由可定义泛型类 (跟函数) 来解决这问题。让我们借由最简单的类容器来检视这点:参照,它可以是空的或者指向某类型的对象。
361+
Scala 借由可定义泛型类 (跟函数) 来解决这问题。让我们借由最简单的类容器来观察这点:引用,它可以是空的或者指向某类型的对象。
362362

363363
class Reference[T] {
364364
private var contents: T = _

0 commit comments

Comments
 (0)