Scala之旅一-基础知识

官方文档

表达式

表达式是可计算的语句。

1
1 + 1

可以使用 println 来输出表达式结果

1
2
3
4
println(1) // 1
println(1 + 1) // 2
println("Hello!") // Hello!
println("Hello," + " world!") // Hello, world!

您可以使用 val 关键字命名表达式的结果。

1
2
val x = 1 + 1
println(x) // 2

命名结果(例如x)称为值。引用值不会重新计算它。

无法重新分配值。

1
x = 3 // 不能通过编译.

值的类型可以被推断出来,但您也可以显式声明类型,如下所示:

1
val x: Int = 1 + 1

注意是如何声明类型的, Int 跟在标识符 x 之后,还需要一个 :

变量

变量就像值,除了你可以重新赋值。您可以使用 var 关键字定义变量。

1
2
3
var x = 1 + 1
x = 3 // 编译通过, 因为 "x" 是用 "var" 关键字声明的。
println(x * x) // 9

与值一样,您可以根据需要明确说明类型:

1
var x: Int = 1 + 1

Blocks

您可以通过用 {} 表达式来组合表达式。我们称之为

块中最后一个表达式的结果也是整个块的结果。

1
2
3
4
println({
val x = 1 + 1
x + 1
}) // 3

函数

函数是带参数的表达式。

您可以定义一个返回给定整数加一的匿名函数(即无名称):

1
(x: Int) => x + 1

方法

方法的外观和行为与函数非常相似,但它们之间存在一些关键差异。

方法使用 def 关键字定义。 def 之后是名称,参数列表,返回类型和正文。

1
2
def add(x: Int, y: Int): Int = x + y
println(add(1, 2)) // 3

注意返回值类型在参数列表后有 :Int

方法可以采用多个参数列表。

1
2
def addThenMultiply(x: Int, y: Int)(multiplier: Int): Int = (x + y) * multiplier
println(addThenMultiply(1, 2)(3)) // 9

或者根本没有参数列表。

1
2
def name: String = System.getProperty("user.name")
println("Hello, " + name + "!")

还有一些其他差异,但就目前而言,您可以将它们视为与函数类似的东西。

方法也可以有多行表达式。

1
2
3
4
def getSquareString(input: Double): String = {
val square = input * input
square.toString
}

方法体中的最后一个表达式是方法的返回值。 (Scala确实有一个 return 关键字,但它很少使用。)

您可以使用 class 关键字定义类,后跟其名称和构造函数参数。

1
2
3
4
class Greeter(prefix: String, suffix: String) {
def greet(name: String): Unit =
println(prefix + name + suffix)
}

方法 greet 的返回类型是 Unit,它表示无返回值。它与 Java和 C 中的void 类似地使用。(不同之处在于,因为每个Scala表达式都必须具有某些值,所以实际上存在Unit类型的单例值,写作()。它不携带任何信息。)

您可以使用 new 关键字创建类的实例。

1
2
val greeter = new Greeter("Hello, ", "!")
greeter.greet("Scala developer") // Hello, Scala developer!

我们后面将深入介绍类。

Case 类

Scala有一种特殊类型的类,称为“case”类。默认情况下,case类是不可变的,并按值进行比较。您可以使用 case class 关键字来定义。

1
case class Point(x: Int, y: Int)

您可以在没有 new 关键字的情况下实例化 Case 类。

1
2
3
val point = Point(1, 2)
val anotherPoint = Point(1, 2)
val yetAnotherPoint = Point(2, 2)

并且它们按值进行比较。

1
2
3
4
5
6
7
8
9
10
11
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 类 还有很多,我们相信你会爱上它们!我们将在稍后深入介绍它们。

对象

对象是它们自己定义的单个实例。你可以把它们想象成是它们自己类中的单例。

您可以使用 object 关键字定义对象。

1
2
3
4
5
6
7
object IdFactory {
private var counter = 0
def create(): Int = {
counter += 1
counter
}
}

您可以通过引用其名称来访问该对象。

1
2
3
4
val newId: Int = IdFactory.create()
println(newId) // 1
val newerId: Int = IdFactory.create()
println(newerId) // 2

我们将在以后深入介绍对象。

Traits

特征?

特征是包含某些字段和方法的类型。可以组合多种特征。

您可以使用 trait 关键字定义特征。

1
2
3
trait Greeter {
def greet(name: String): Unit
}

特征也可以有默认实现。

1
2
3
4
trait Greeter {
def greet(name: String): Unit =
println("Hello, " + name + "!")
}

您可以使用 extends 关键字扩展 traits 并使用 override 关键字覆盖实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
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?

在这里,DefaultGreeter 只扩展了一个特征,但它可以扩展多个特征。 我们稍后将深入介绍特征。

Main 方法

Main方法是程序的入口点。 Java虚拟机需要将main方法命名为 main,并接收一个字符串数组参数。

使用对象,您可以按如下方式定义main方法:

1
2
3
4
object Main {
def main(args: Array[String]): Unit =
println("Hello, Scala developer!")
}
0%
隐藏