ZetCode

Scala 基础

最后修改于 2023 年 1 月 10 日

在本文中,我们将介绍 Scala 语言的基本编程概念。

Scala

Scala 是一种强大的、高级的面向对象和函数式编程语言,用于 JVM。它具有先进的类型系统。Scala 与 Java API 无缝集成。Scala 于 2004 年首次出现。

2021 年,Scala 3 发布。它是对该语言的一次重大重写。

Scala 简单示例

以下是 Scala 3 中的一个简单示例。

main.scala
@main def main() =

    println("Scala language")

该程序将一条消息打印到控制台。Scala 程序具有 .scala 扩展名。main 函数是程序的入口点。它带有 @main 注解。

Scala 3 使用缩进分隔函数体。

println("Scala language")

println 函数在控制台中显示消息。不必用分号结束语句。

$ scala main.scala
Scala language

我们使用 scala 代码运行器执行程序。

Scala 注释

注释用于人类来澄清源代码。Dart 中有三种类型的注释:单行注释(//)、多行注释(/* */)和文档注释(/** */)。

文档注释用于生成文档。IDE 也使用它们。

main.scala
/*
  main.scala
  Author: Jan Bodnar
  ZetCode 2022
*/

// Program starts here
@main def main() =
    print("This is a Scala program")

在示例中,我们有一个多行注释和一个单行注释。注释被编译器或代码运行器忽略。

Scala 值

Scala 值是赋予值的不可变名称/标识符。它们使用 val 关键字创建。

main.scala
@main def main() =

    val name: String = "John Doe"
    val age: Int = 34
    val height: Double = 172.5

    println(s"$name is $age years old; his height is $height cm")

在示例中,我们定义了三个值。

val name: String = "John Doe"

字符串值绑定到 name 标识符。字符串是包含在两个双引号之间的数据类型。标识符后跟一个冒号字符和值的_数据类型。

val age: Int = 34

这里我们定义了一个整数值。

val height: Double = 172.5

这里我们定义了一个双精度浮点值。

println(s"$name is $age years old; his height is $height cm")

这三个标识符被传递给插值字符串,以形成一个消息。在插值字符串中,以美元符号为前缀的标识符在字符串构建时会被其内容替换。插值字符串以 s 字符为前缀。

$ scala values.scala
John Doe is 34 years old; his height is 172.5 cm

Scala 类型推断

Scala 可以推断值的类型;因此,在许多情况下,我们可以省略显式类型声明。

main.scala
@main def main() =

    val name = "John Doe"
    val age = 34
    val height = 172.5

    println(s"$name is $age years old; his height is $height cm")

    println(name.getClass)
    println(age.getClass)
    println(height.getClass)

Scala 编译器/运行器可以从赋值的右侧推断数据类型。

println(name.getClass)
println(age.getClass)
println(height.getClass)

我们可以使用 getClass 获取标识符的数据类型。

$ scala main.scala
John Doe is 34 years old; his height is 172.5 cm
class java.lang.String
int
double

Scala 变量

Scala 变量是可变标识符。它们使用 var 关键字创建。

main.scala
@main def main() =

    var name = "John Doe"
    var age = 34
    var height = 172.5

    println(s"$name is $age years old; his height is $height cm")

    name = "Roger Roe"
    age = 57
    height = 167.7

    println(s"$name is $age years old; his height is $height cm")

我们定义了三个变量。稍后,我们将新值赋给这些变量。

$ scala main.scala
John Doe is 34 years old; his height is 172.5 cm
Roger Roe is 57 years old; his height is 167.7 cm

Scala 读取输入

Scala 的 io.SdtIn 包提供了标准输入/输出例程。

main.scala
@main def main() =

    print("Enter your name: ")

    val name = io.StdIn.readLine

    printf("Hello %s!\n", name)

readLine 从终端读取整行。

val name = io.StdIn.readLine

readLine 方法的完整路径是 io.StdIn.readLine。该方法返回从用户读取的输入,并将其赋给 name 标识符。

$ scala main.scala
Enter your name: Peter
Hello Peter!

Scala 条件语句

条件语句是控制流结构。它们使用 if thenelse ifelse 关键字创建。

main.scala
import scala.util.Random

@main def main() =

    val r = Random.between(-5, 6)

    if r > 0 then
        println("positive value")
    else if r == 0 then
        println("zero")
    else
        println("negative value")
    end if

在示例中,我们生成一个随机数。根据接收到的值,我们将一条消息打印到控制台。

import scala.util.Random

我们从标准库导入 Random 类。现在我们可以不带完整路径地引用该类。

val r = Random.between(-5, 6)

我们获取指定值之间的随机整数。下界包含在内,上界不包含在内。

if r > 0 then
    println("positive value")
else if r == 0 then
    println("zero")
else
    println("negative value")
end if

根据生成的随机值,可以执行三个分支。只有一个分支会被执行;其他分支会被跳过。end if 关键字是可选的;可以省略。

Scala 函数

函数是将零个或多个输入参数映射到零个或多个输出参数。函数可以减少代码重复。

函数可以赋给变量、作为参数传递给函数或从函数返回。

main.scala
val square = (x: Int) => x * x
val triple = (x: Int) => x * x * x

@main def main() =

    val res = square(3)
    println(res)

    val res2 = triple(5)
    println(res2)

在程序中,我们定义了两个函数:squaretriple

val square = (x: Int) => x * x

函数名后跟 = 字符和一个括号对,它们指定函数的参数。在本例中,我们期望一个整数参数。函数体跟在 => 运算符之后。表达式的计算值将被返回给调用者。

请注意,我们必须显式输入至少一个输入参数;否则,Scala 无法确定使用的类型。

val res = square(3)
println(res)

我们调用 square 函数并传递一个数字。返回值赋给 res 标识符,然后使用 println 打印。

$ scala main.scala 
9
125

Scala while 循环

while 循环是一种控制流语句,它允许代码根据给定的布尔条件重复执行。while 关键字执行 do 关键字之后的块内的语句。每次表达式求值为 true 时,都会执行这些语句。

main.scala
@main def main() =

    var i = 0
    var msum = 0

    while i <= 10 do

        msum += i
        i += 1

    println(msum)

我们计算一个数字范围内的值之和。

while 循环有三个部分:初始化、测试和更新。每次执行语句称为一个周期。

var i = 0
var msum = 0

首先,我们将 i 计数器和最终结果 msum 初始化为零。

while i <= 10 do

    msum += i
    i += 1

while 块中 do 关键字之后的表达式是第二阶段,即测试。主体中的语句将一直执行,直到表达式求值为 false。+= 是一个复合运算符,等同于 i = i + 1

println(msum)

循环终止后,我们打印计算出的值。

$ scala main.scala
55

Scala for 循环

for 循环是一种基本的控制流结构。它可用于遍历值序列。

main.scala
@main def main() =

    val nums = List[Int](1, 2, 3, 4, 5, 6)

    for e <- nums do
        println(e)

    println("-----------------")

    for e <- 1 to 5 do println(e)

在示例中,我们遍历了整数列表和整数范围。

val nums = List[Int](1, 2, 3, 4, 5, 6)

List 是基本的数据集合。在本例中,我们将整数值存储在列表中。列表的类型在 [] 方括号中指定。

for e <- nums do
    println(e)

我们通过 for 循环遍历列表元素。每个周期执行的语句块跟在 do 关键字之后。在每个周期中,e 标识符包含当前列表值。

for e <- 1 to 5 do println(e)

我们可以使用 for 循环遍历值范围。范围使用 to 关键字创建。

$ scala main.scala 
1
2
3
4
5
6
-----------------
1
2
3
4
5

Scala 命令行参数

Scala 程序可以接收命令行参数。当我们在运行程序时,它们跟在程序名称后面。

main.scala
@main def main(vals: Int*) =

    val sum = vals.sum
    println(sum)

我们在 vals 序列中接收参数。我们使用 sum 方法计算整数的和。

@main def main(vals: Int*) =

Int* 用于表示可变数量的参数。

$ scala main.scala 1 2 3 4 5
15

在本文中,我们介绍了 Scala 语言的基础知识。