From 4ed89bcfd02e9dcf974003bf403706478fd6f30d Mon Sep 17 00:00:00 2001 From: coalchan Date: Sun, 22 Jul 2018 17:53:30 +0800 Subject: [PATCH 1/5] Add Chinese translation of basics --- _zh-cn/tour/basics.md | 323 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 323 insertions(+) create mode 100644 _zh-cn/tour/basics.md diff --git a/_zh-cn/tour/basics.md b/_zh-cn/tour/basics.md new file mode 100644 index 0000000000..01347666e2 --- /dev/null +++ b/_zh-cn/tour/basics.md @@ -0,0 +1,323 @@ +--- +layout: tour +title: 基础 + +discourse: false + +partof: scala-tour + +num: 2 +language: zh-cn +next-page: unified-types +previous-page: tour-of-scala + +redirect_from: "/tutorials/tour/basics.html" +--- + +这篇文章涵盖了Scala的基础知识。 + +## 在浏览器上尝试Scala + +你可以在浏览器上使用ScalaFiddle运行Scala。 + +1. 打开[https://scalafiddle.io](https://scalafiddle.io); +2. 在左侧窗格中粘贴`println("Hello, world!")`; +3. 点击"Run"按钮,输出将展现在右侧窗格中。 + +这是一种简单的、零设置的方法来实践Scala的代码片段。 + +这篇文档中的大部分代码示例集成了ScalaFiddle,所以你可以直接点击“Run"按钮来实践。 + +## 表达式 + +表达式是可计算的语句。 +``` +1 + 1 +``` +你可以使用`println`来输出表达式的结果。 + +{% scalafiddle %} +```tut +println(1) // 1 +println(1 + 1) // 2 +println("Hello!") // Hello! +println("Hello," + " world!") // Hello, world! +``` +{% endscalafiddle %} + +### 常量 + +你可以使用`val`关键字来给表达式的结果命名。 + +```tut +val x = 1 + 1 +println(x) // 2 +``` + +对于结果比如这里的`x`的命名,被称为常量。引用一个常量不会再次计算。 + +常量不能重新被赋值。 + +```tut:nofail +val x = 1 + 1 +x = 3 // This does not compile. +``` + +常量的类型可以被推断,或者你也可以显示地声明类型,例如: + +```tut +val x: Int = 1 + 1 +``` + +注意下,在标识符`x`的后面,类型声明`Int`是怎么出现的。这里你还需要一个`:`。 + +### 变量 + +除了可以重新赋值,变量和常量类似。你可以使用`var`关键字来定义一个变量。 + +```tut +var x = 1 + 1 +x = 3 // This compiles because "x" is declared with the "var" keyword. +println(x * x) // 9 +``` + +和常量一样,你可以显示地声明类型: + +```tut +var x: Int = 1 + 1 +``` + + +## 块(Blocks) + +你可以组合几个表达式,并且用`{}`包围起来。我们称之为块(block)。 + +这个块中最后一个表达式的结果,也正是整个块的结果。 + +```tut +println({ + val x = 1 + 1 + x + 1 +}) // 3 +``` + +## 函数 + +函数是接受参数的表达式。 + +你可以定义一个匿名函数(即没有名字),来返回一个给定整数加一的结果。 + +```tut +(x: Int) => x + 1 +``` + +`=>`的左边是参数列表,右边是一个包含参数的表达式。 + +你也可以给函数命名。 + +{% scalafiddle %} +```tut +val addOne = (x: Int) => x + 1 +println(addOne(1)) // 2 +``` +{% endscalafiddle %} + +函数可以接受多个参数。 + +{% scalafiddle %} +```tut +val add = (x: Int, y: Int) => x + y +println(add(1, 2)) // 3 +``` +{% endscalafiddle %} + +或者不接受参数。 + +```tut +val getTheAnswer = () => 42 +println(getTheAnswer()) // 42 +``` + +## 方法 + +方法的表现和行为和函数非常类似,但是它们之间有一些关键的差别。 + +方法由`def`关键字定义。`def`后面跟着一个名字、参数列表、返回类型和方法体。 + +{% scalafiddle %} +```tut +def add(x: Int, y: Int): Int = x + y +println(add(1, 2)) // 3 +``` +{% endscalafiddle %} + +注意返回类型是怎么在函数列表和一个冒号`: Int`之后声明的。 + +方法可以接受多个参数列表。 + +{% scalafiddle %} +```tut +def addThenMultiply(x: Int, y: Int)(multiplier: Int): Int = (x + y) * multiplier +println(addThenMultiply(1, 2)(3)) // 9 +``` +{% endscalafiddle %} + +或者没有参数列表。 + +```tut +def name: String = System.getProperty("user.name") +println("Hello, " + name + "!") +``` + +还有一些其他的区别,但是现在你可以认为方法就是类似于函数的东西。 + +方法也可以有多行的表达式。 +```tut +def getSquareString(input: Double): String = { + val square = input * input + square.toString +} +``` +方法体的最后一个表达式就是方法的返回值。(Scala中也有一个`return`关键字,但是很少使用) + +## 类 + +你可以使用`class`关键字定义一个类,后面跟着它的名字和构造参数。 + +```tut +class Greeter(prefix: String, suffix: String) { + def greet(name: String): Unit = + println(prefix + name + suffix) +} +``` +`greet`方法的返回类型是`Unit`,表明没有什么有意义的需要返回。它有点像Java和C语言中的`void`。(不同点在于每个Scala表达式都必须有值,事实上有个`Unit`类型的单例值,写作`()`,它不携带任何信息) + +你可以使用`new`关键字创建一个类的实例。 + +```tut +val greeter = new Greeter("Hello, ", "!") +greeter.greet("Scala developer") // Hello, Scala developer! +``` + +我们将在[后面](classes.html)深入介绍类。 + +## 样例类 + +Scala有一种特殊的类叫做样例类(case class)。默认情况下,样例类一般用于不可变对象,并且可作值比较。你可以使用`case class`关键字来定义样例类。 + +```tut +case class Point(x: Int, y: Int) +``` + +你可以不用`new`关键字来实例化样例类。 + +```tut +val point = Point(1, 2) +val anotherPoint = Point(1, 2) +val yetAnotherPoint = Point(2, 2) +``` + +并且它们可以进行值比较。 + +```tut +if (point == anotherPoint) { + println(point + " and " + anotherPoint + " are the same.") +} else { + println(point + " and " + anotherPoint + " are different.") +} +// Point(1,2) and Point(1,2) are the same. + +if (point == yetAnotherPoint) { + println(point + " and " + yetAnotherPoint + " are the same.") +} else { + println(point + " and " + yetAnotherPoint + " are different.") +} +// Point(1,2) and Point(2,2) are different. +``` + +关于样例类,还有不少内容我们乐于介绍,并且我们确信你会爱上它们。我们会在[后面](case-classes.html)深入介绍它们。 + +## 对象 + +对象是它们自己定义的单实例,你可以把它看作它自己的类的单例。 + +你可以使用`object`关键字定义对象。 + +```tut +object IdFactory { + private var counter = 0 + def create(): Int = { + counter += 1 + counter + } +} +``` + +你可以通过引用它的名字来访问一个对象。 + +```tut +val newId: Int = IdFactory.create() +println(newId) // 1 +val newerId: Int = IdFactory.create() +println(newerId) // 2 +``` + +我们会在[后面](singleton-objects.html)深入介绍它们。 + +## 特质 + +特质是包含某些字段和方法的类型。可以组合多个特质。 + +你可以使用`trait`关键字定义特质。 + +```tut +trait Greeter { + def greet(name: String): Unit +} +``` + +特质也可以有默认的实现。 + +{% scalafiddle %} +```tut +trait Greeter { + def greet(name: String): Unit = + println("Hello, " + name + "!") +} +``` + +你可以使用`extends`关键字来继承特质,使用`override`关键字来覆盖默认的实现。 + +```tut +class DefaultGreeter extends Greeter + +class CustomizableGreeter(prefix: String, postfix: String) extends Greeter { + override def greet(name: String): Unit = { + println(prefix + name + postfix) + } +} + +val greeter = new DefaultGreeter() +greeter.greet("Scala developer") // Hello, Scala developer! + +val customGreeter = new CustomizableGreeter("How are you, ", "?") +customGreeter.greet("Scala developer") // How are you, Scala developer? +``` +{% endscalafiddle %} + +这里,`DefaultGreeter`仅仅继承了一个特质,它还可以继承多个特质。 + +我们会在[后面](traits.html)深入介绍特质。 + +## 主方法 + +主方法是一个程序的入口点。JVM要求一个名为`main`的主方法,接受一个字符串数组的参数。 + +通过使用对象,你可以如下所示来定义一个主方法。 + +```tut +object Main { + def main(args: Array[String]): Unit = + println("Hello, Scala developer!") +} +``` From 30df14542253e6b865a644a708ebb38cc84cedf3 Mon Sep 17 00:00:00 2001 From: coalchan Date: Mon, 23 Jul 2018 23:05:32 +0800 Subject: [PATCH 2/5] Add Chinese translation of unified-types --- _zh-cn/tour/unified-types.md | 84 ++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 _zh-cn/tour/unified-types.md diff --git a/_zh-cn/tour/unified-types.md b/_zh-cn/tour/unified-types.md new file mode 100644 index 0000000000..72f57a9c7d --- /dev/null +++ b/_zh-cn/tour/unified-types.md @@ -0,0 +1,84 @@ +--- +layout: tour +title: 统一类型 + +discourse: true + +partof: scala-tour + +num: 3 +language: zh-cn +next-page: classes +previous-page: basics +prerequisite-knowledge: classes, basics + +redirect_from: "/tutorials/tour/unified-types.html" +--- + +在Scala中,所有的值都有类型,包括数值和函数。下图阐述了类型层次结构的一个子集。 + +Scala Type Hierarchy + +## Scala类型层次结构 ## + +[`Any`](http://www.scala-lang.org/api/2.12.1/scala/Any.html)是所有类型的超类型,也称为顶级类 +型。它定义了一些通用的方法如`equals`、`hashCode`和`toString`。`Any`有两个直接子类:`AnyVal`和`AnyRef`。 + +`AnyVal`代表值类型。有9个预定义的非空的值类型分别是:`Double`、`Float`、`Long`、`Int`、`Short`、`Byte`、`Char`、`Unit`和`Boolean`。`Unit`是不带任何意义的值类型,它仅有一个实例可以像这样声明:`()`。所有的函数必须有返回,所以说有时候`Unit`也是有用的返回类型。 + +`AnyRef`代表引用类型。所有非值类型都被定义为引用类型。在Scala中,每个用户自定义的类型都是`AnyRef`的子类型。如果Scala被应用在Java的运行环境中,`AnyRef`相当于`java.lang.Object`。 + +这里有一个例子,说明了字符串、整型、布尔值和函数都是对象,这一点和其他对象一样: + +```tut +val list: List[Any] = List( + "a string", + 732, // an integer + 'c', // a character + true, // a boolean value + () => "an anonymous function returning a string" +) + +list.foreach(element => println(element)) +``` + +这里定义了一个类型`List`的变量`list`。这个列表里由多种类型进行初始化,但是它们都是`scala.Any`的实例,所以可以把它们加入到列表中。 + +下面是程序的输出: + +``` +a string +732 +c +true + +``` + +## 类型转换 +值类型可以按照下面的方向进行转换: +Scala Type Hierarchy + +例如: + +```tut +val x: Long = 987654321 +val y: Float = x // 9.8765434E8 (note that some precision is lost in this case) + +val face: Char = '☺' +val number: Int = face // 9786 +``` + +转换是单向,且不是编译期的。 + +``` +val x: Long = 987654321 +val y: Float = x // 9.8765434E8 +val z: Long = y // Does not conform +``` + +你可以将一个类型转换为子类型,这点将在后面的文章介绍。 + +## Nothing和Null +`Nothing`是所有类型的子类型,也称为底部类型。没有一个值是`Nothing`类型的。它的用途之一是给出非正常终止的信号,如抛出异常、程序退出或者一个无限循环(可以理解为它是一个不对值进行定义的表达式的类型,或者是一个不能正常返回的方法)。 + +`Null`是所有引用类型的子类型(即`AnyRef`的任意子类型)。它有一个单例值由关键字`null`所定义。`Null`主要用于和其他JVM语言的互操作性,但是几乎不应该在Scala代码中使用。我们将在后面的章节中介绍`null`的替代方案。 From 9d9f91af20e2c376cada6bab976ef6d828821837 Mon Sep 17 00:00:00 2001 From: coalchan Date: Mon, 23 Jul 2018 23:07:23 +0800 Subject: [PATCH 3/5] Update Chinese translation of interoperates in tour-of-scala --- _zh-cn/tour/tour-of-scala.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_zh-cn/tour/tour-of-scala.md b/_zh-cn/tour/tour-of-scala.md index 84952d4480..7f08aad362 100644 --- a/_zh-cn/tour/tour-of-scala.md +++ b/_zh-cn/tour/tour-of-scala.md @@ -53,9 +53,9 @@ Scala配备了一个拥有强大表达能力的类型系统,它可以静态地 * [隐式类](http://docs.scala-lang.org/overviews/core/implicit-classes.html)允许给已有的类型添加扩展方法。 * [字符串插值](/overviews/core/string-interpolation.html)可以让用户使用自定义的插值器进行扩展。 -## Scala的交互 +## Scala的互操作性 -通过使用流行的Java运行环境(JRE),Scala设计了很好的交互。特别是与主流的面向对象的Java编程语言的交互尽可能的平滑。Java的最新特性如函数接口(SAMs)、[lambda表达式](higher-order-functions.html)、[注解](annotations.html)及[泛型类](generic-classes.html) 在Scala中都有类似的实现。 +Scala设计的目标是与流行的Java运行环境(JRE)进行良好的互操作,特别是与主流的面向对象编程语言——Java的互操作尽可能的平滑。Java的最新特性如函数接口(SAMs)、[lambda表达式](higher-order-functions.html)、[注解](annotations.html)及[泛型类](generic-classes.html) 在Scala中都有类似的实现。 另外有些Java中并没有的特性,如[缺省参数值](default-parameter-values.html)和[带名字的参数](named-arguments.html)等,也是尽可能地向Java靠拢。Scala拥有类似Java的编译模型(独立编译、动态类加载),且允许使用已有的成千上万的高质量类库。 From ca61342dedd44047cf3628218089dbe64470fd57 Mon Sep 17 00:00:00 2001 From: coalchan Date: Wed, 1 Aug 2018 23:29:24 +0800 Subject: [PATCH 4/5] Add Chinese translation of classes --- _zh-cn/tour/classes.md | 110 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 _zh-cn/tour/classes.md diff --git a/_zh-cn/tour/classes.md b/_zh-cn/tour/classes.md new file mode 100644 index 0000000000..7e8a6cdc20 --- /dev/null +++ b/_zh-cn/tour/classes.md @@ -0,0 +1,110 @@ +--- +layout: tour +title: 类 + +discourse: true + +partof: scala-tour + +language: zh-cn +num: 4 +next-page: traits +previous-page: unified-types +topics: classes +prerequisite-knowledge: no-return-keyword, type-declaration-syntax, string-interpolation, procedures + +redirect_from: "/tutorials/tour/classes.html" +--- + +Scala中的类是用于创建对象的蓝图,其中包含了方法、常量、变量、类型、对象、特质、类,这些统称为成员。类型、对象和特质将在后面的文章中介绍。 + +## 类定义 +一个最简的类的定义就是关键字`class`+标识符,类名必须是大写。 +```tut +class User + +val user1 = new User +``` +关键字`new`被用于创建类的实例。`User`由于没有定义任何构造器,因而只有一个不接受任何参数的默认构造器。然而,你通常需要一个构造器和类体。下面是类定义的一个例子: + +```tut +class Point(var x: Int, var y: Int) { + + def move(dx: Int, dy: Int): Unit = { + x = x + dx + y = y + dy + } + + override def toString: String = + s"($x, $y)" +} + +val point1 = new Point(2, 3) +point1.x // 2 +println(point1) // prints (2, 3) +``` + +`Point`类有4个成员:变量`x`和`y`,方法`move`和`toString`。与许多其他语言不同,主构造方法在类的签名中`(var x: Int, var y: Int)`。`move`方法接受2个参数,返回无任何意义的`Unit`类型值`()`。这一点与Java这类语言中的`void`相当。另外,`toString`方法不接受任何参数但是返回一个`String`值。因为`toString`覆盖了[`AnyRef`](unified-types.html)中的`toString`方法,所以用了`override`关键字标记。 + +## 构造器 + +构造器可以通过提供一个默认值来拥有可选参数: + +```tut +class Point(var x: Int = 0, var y: Int = 0) + +val origin = new Point // x and y are both set to 0 +val point1 = new Point(1) +println(point1.x) // prints 1 + +``` + +在这个版本的`Point`类中,`x`和`y`拥有默认值`0`所以没有必传参数。然而,因为构造器是从左往右读取参数,所以如果仅仅要传个`y`的值,你需要带名传参。 +``` +class Point(var x: Int = 0, var y: Int = 0) +val point2 = new Point(y=2) +println(point2.y) // prints 2 +``` + +这样的做法在实践中有利于使得表达明确无误。 + +## 私有成员和Getter/Setter语法 +成员默认是公有(`public`)的。使用`private`访问修饰符可以在函数外部隐藏它们。 +```tut +class Point { + private var _x = 0 + private var _y = 0 + private val bound = 100 + + def x = _x + def x_= (newValue: Int): Unit = { + if (newValue < bound) _x = newValue else printWarning + } + + def y = _y + def y_= (newValue: Int): Unit = { + if (newValue < bound) _y = newValue else printWarning + } + + private def printWarning = println("WARNING: Out of bounds") +} + +val point1 = new Point +point1.x = 99 +point1.y = 101 // prints the warning +``` +在这个版本的`Point`类中,数据存在私有变量`_x`和`_y`中。`def x`和`def y`方法用于访问私有数据。`def x_=`和`def y_=`是为了验证和给`_x`和`_y`赋值。注意下对于setter方法的特殊语法:这个方法在getter方法的后面加上`_=`,后面跟着参数。 + +主构造方法中带有`val`和`var`的参数时公有的。然而由于`val`是不可变的,所以不能像下面这样去使用。 +``` +class Point(val x: Int, val y: Int) +val point = new Point(1, 2) +point.x = 3 // <-- does not compile +``` + +不带`val`或`var`的参数是私有的,仅在类中可见。 +``` +class Point(x: Int, y: Int) +val point = new Point(1, 2) +point.x // <-- does not compile +``` From e82b7be93575090e71e5a61d850067c96587ca87 Mon Sep 17 00:00:00 2001 From: coalchan Date: Sun, 12 Aug 2018 12:44:53 +0800 Subject: [PATCH 5/5] Modify the translation of some terms in tour of scala --- _zh-cn/tour/basics.md | 26 +++++++++++++------------- _zh-cn/tour/classes.md | 4 ++-- _zh-cn/tour/unified-types.md | 4 ++-- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/_zh-cn/tour/basics.md b/_zh-cn/tour/basics.md index 01347666e2..9d9e46abc1 100644 --- a/_zh-cn/tour/basics.md +++ b/_zh-cn/tour/basics.md @@ -26,7 +26,7 @@ redirect_from: "/tutorials/tour/basics.html" 这是一种简单的、零设置的方法来实践Scala的代码片段。 -这篇文档中的大部分代码示例集成了ScalaFiddle,所以你可以直接点击“Run"按钮来实践。 +这篇文档中的大部分代码示例集成了ScalaFiddle,直接点击“Run"按钮即可运行。 ## 表达式 @@ -45,7 +45,7 @@ println("Hello," + " world!") // Hello, world! ``` {% endscalafiddle %} -### 常量 +### 常量(`Values`) 你可以使用`val`关键字来给表达式的结果命名。 @@ -54,22 +54,22 @@ val x = 1 + 1 println(x) // 2 ``` -对于结果比如这里的`x`的命名,被称为常量。引用一个常量不会再次计算。 +对于结果比如这里的`x`的命名,被称为常量(`values`)。引用一个常量(`value`)不会再次计算。 -常量不能重新被赋值。 +常量(`values`)不能重新被赋值。 ```tut:nofail val x = 1 + 1 x = 3 // This does not compile. ``` -常量的类型可以被推断,或者你也可以显示地声明类型,例如: +常量(`values`)的类型可以被推断,或者你也可以显示地声明类型,例如: ```tut val x: Int = 1 + 1 ``` -注意下,在标识符`x`的后面,类型声明`Int`是怎么出现的。这里你还需要一个`:`。 +注意下,在标识符`x`的后面、类型声明`Int`的前面,还需要一个冒号`:`。 ### 变量 @@ -88,11 +88,11 @@ var x: Int = 1 + 1 ``` -## 块(Blocks) +## 代码块(Blocks) -你可以组合几个表达式,并且用`{}`包围起来。我们称之为块(block)。 +你可以组合几个表达式,并且用`{}`包围起来。我们称之为代码块(block)。 -这个块中最后一个表达式的结果,也正是整个块的结果。 +代码块中最后一个表达式的结果,也正是整个块的结果。 ```tut println({ @@ -103,7 +103,7 @@ println({ ## 函数 -函数是接受参数的表达式。 +函数是带有参数的表达式。 你可以定义一个匿名函数(即没有名字),来返回一个给定整数加一的结果。 @@ -122,7 +122,7 @@ println(addOne(1)) // 2 ``` {% endscalafiddle %} -函数可以接受多个参数。 +函数可带有多个参数。 {% scalafiddle %} ```tut @@ -131,7 +131,7 @@ println(add(1, 2)) // 3 ``` {% endscalafiddle %} -或者不接受参数。 +或者不带参数。 ```tut val getTheAnswer = () => 42 @@ -217,7 +217,7 @@ val anotherPoint = Point(1, 2) val yetAnotherPoint = Point(2, 2) ``` -并且它们可以进行值比较。 +并且它们的值可以进行比较。 ```tut if (point == anotherPoint) { diff --git a/_zh-cn/tour/classes.md b/_zh-cn/tour/classes.md index 7e8a6cdc20..7439128bcb 100644 --- a/_zh-cn/tour/classes.md +++ b/_zh-cn/tour/classes.md @@ -25,7 +25,7 @@ class User val user1 = new User ``` -关键字`new`被用于创建类的实例。`User`由于没有定义任何构造器,因而只有一个不接受任何参数的默认构造器。然而,你通常需要一个构造器和类体。下面是类定义的一个例子: +关键字`new`被用于创建类的实例。`User`由于没有定义任何构造器,因而只有一个不带任何参数的默认构造器。然而,你通常需要一个构造器和类体。下面是类定义的一个例子: ```tut class Point(var x: Int, var y: Int) { @@ -44,7 +44,7 @@ point1.x // 2 println(point1) // prints (2, 3) ``` -`Point`类有4个成员:变量`x`和`y`,方法`move`和`toString`。与许多其他语言不同,主构造方法在类的签名中`(var x: Int, var y: Int)`。`move`方法接受2个参数,返回无任何意义的`Unit`类型值`()`。这一点与Java这类语言中的`void`相当。另外,`toString`方法不接受任何参数但是返回一个`String`值。因为`toString`覆盖了[`AnyRef`](unified-types.html)中的`toString`方法,所以用了`override`关键字标记。 +`Point`类有4个成员:变量`x`和`y`,方法`move`和`toString`。与许多其他语言不同,主构造方法在类的签名中`(var x: Int, var y: Int)`。`move`方法带有2个参数,返回无任何意义的`Unit`类型值`()`。这一点与Java这类语言中的`void`相当。另外,`toString`方法不带任何参数但是返回一个`String`值。因为`toString`覆盖了[`AnyRef`](unified-types.html)中的`toString`方法,所以用了`override`关键字标记。 ## 构造器 diff --git a/_zh-cn/tour/unified-types.md b/_zh-cn/tour/unified-types.md index 72f57a9c7d..52e6091fb5 100644 --- a/_zh-cn/tour/unified-types.md +++ b/_zh-cn/tour/unified-types.md @@ -68,7 +68,7 @@ val face: Char = '☺' val number: Int = face // 9786 ``` -转换是单向,且不是编译期的。 +转换是单向,下面这样写将不会通过编译。 ``` val x: Long = 987654321 @@ -81,4 +81,4 @@ val z: Long = y // Does not conform ## Nothing和Null `Nothing`是所有类型的子类型,也称为底部类型。没有一个值是`Nothing`类型的。它的用途之一是给出非正常终止的信号,如抛出异常、程序退出或者一个无限循环(可以理解为它是一个不对值进行定义的表达式的类型,或者是一个不能正常返回的方法)。 -`Null`是所有引用类型的子类型(即`AnyRef`的任意子类型)。它有一个单例值由关键字`null`所定义。`Null`主要用于和其他JVM语言的互操作性,但是几乎不应该在Scala代码中使用。我们将在后面的章节中介绍`null`的替代方案。 +`Null`是所有引用类型的子类型(即`AnyRef`的任意子类型)。它有一个单例值由关键字`null`所定义。`Null`主要是使得Scala满足和其他JVM语言的互操作性,但是几乎不应该在Scala代码中使用。我们将在后面的章节中介绍`null`的替代方案。