Scala 3 — 书籍

Scala 特性

语言

Scala 这个名字源自单词 scalable,正如其名,Scala 语言用于支持繁忙的网站并分析海量数据集。本部分介绍了使 Scala 成为可扩展语言的特性。这些特性分为三个部分

  • 高级语言特性
  • 低级语言特性
  • Scala 生态系统特性

高级特性

从谚语所说的“30,000 英尺的视角”来看 Scala,你可以做出以下陈述

  • 它是一种高级编程语言
  • 它具有简洁易读的语法
  • 它是静态类型的(但感觉是动态的)
  • 它具有表达性类型系统
  • 它是一种函数式编程 (FP) 语言
  • 它是一种面向对象编程 (OOP) 语言
  • 它支持 FP 和 OOP 的融合
  • 上下文抽象提供了一种实现术语推断的清晰方法
  • 它在 JVM(和浏览器中)运行
  • 它与 Java 代码无缝交互
  • 它用于服务器端应用程序(包括微服务)、大数据应用程序,还可以与 Scala.js 一起在浏览器中使用

以下部分将快速浏览这些功能。

高级语言

Scala 至少在两个方面被认为是一种高级语言。首先,与 Java 和许多其他现代语言一样,您不必处理指针和内存管理等低级概念。

其次,通过使用 lambda 和高阶函数,您可以在非常高的级别编写代码。正如函数式编程所说,在 Scala 中,您编写想要的内容,而不是如何实现它。也就是说,我们不编写这样的命令式代码

import scala.collection.mutable.ListBuffer

def double(ints: List[Int]): List[Int] = {
  val buffer = new ListBuffer[Int]()
  for (i <- ints) {
    buffer += i * 2
  }
  buffer.toList
}

val oldNumbers = List(1, 2, 3)
val newNumbers = double(oldNumbers)
import scala.collection.mutable.ListBuffer

def double(ints: List[Int]): List[Int] =
  val buffer = new ListBuffer[Int]()
  for i <- ints do
    buffer += i * 2
  buffer.toList

val oldNumbers = List(1, 2, 3)
val newNumbers = double(oldNumbers)

该代码逐步指示编译器要做什么。相反,我们编写高级函数式代码,使用高阶函数和 lambda 来计算相同的结果

val newNumbers = oldNumbers.map(_ * 2)

如您所见,该代码简洁得多,更易于阅读和维护。

简洁的语法

Scala 具有简洁、可读的语法。例如,变量的创建简洁,并且它们的类型很清楚

val nums = List(1,2,3)
val p = Person("Martin", "Odersky")

高阶函数和 lambda 使简洁的代码易于阅读

nums.map(i => i * 2)   // long form
nums.map(_ * 2)        // short form

nums.filter(i => i > 1)
nums.filter(_ > 1)

特征、类和方法使用简洁、轻量级的语法定义

trait Animal {
  def speak(): Unit
}

trait HasTail {
  def wagTail(): Unit
}

class Dog extends Animal with HasTail {
  def speak(): Unit = println("Woof")
  def wagTail(): Unit = println("⎞⎜⎛  ⎞⎜⎛")
}
trait Animal:
  def speak(): Unit

trait HasTail:
  def wagTail(): Unit

class Dog extends Animal, HasTail:
  def speak(): Unit = println("Woof")
  def wagTail(): Unit = println("⎞⎜⎛  ⎞⎜⎛")

研究表明,开发人员阅读代码与编写代码的时间比例至少为 10:1,因此编写简洁可读的代码非常重要。

动态的感觉

Scala 是一种静态类型语言,但由于其类型推断能力,它感觉是动态的。所有这些表达式看起来像 Python 或 Ruby 等动态类型语言,但它们都是 Scala

val s = "Hello"
val p = Person("Al", "Pacino")
val sum = nums.reduceLeft(_ + _)
val y = for (i <- nums) yield i * 2
val z = nums
  .filter(_ > 100)
  .filter(_ < 10_000)
  .map(_ * 2)
val s = "Hello"
val p = Person("Al", "Pacino")
val sum = nums.reduceLeft(_ + _)
val y = for i <- nums yield i * 2
val z = nums
  .filter(_ > 100)
  .filter(_ < 10_000)
  .map(_ * 2)

正如 Heather Miller 所说,Scala 被认为是一种强静态类型语言,您可以获得静态类型的所有好处

  • 正确性:您在编译时捕获大多数错误
  • 出色的 IDE 支持
    • 可靠的代码补全
    • 在编译时捕获错误意味着在键入时捕获错误
    • 轻松可靠的重构
  • 您可以自信地重构代码
  • 方法类型声明告诉读者方法的作用,并有助于作为文档
  • 可扩展性和可维护性:类型有助于确保任意大型应用程序和开发团队的正确性
  • 强类型与出色的推断相结合,启用了诸如上下文抽象之类的机制,它允许您省略样板代码。通常,此样板代码可以根据类型定义和给定上下文由编译器推断。

表现力丰富的类型系统

Scala 的类型系统在编译时强制以安全且连贯的方式使用抽象。特别是,类型系统支持

结合起来,这些特性为安全重用编程抽象和软件类型安全扩展提供了强大的基础。

一种函数式编程语言

Scala 是一种函数式编程 (FP) 语言,这意味着

  • 函数是值,可以像任何其他值一样传递
  • 直接支持高阶函数
  • 内置 lambda
  • Scala 中的一切都是返回值的表达式
  • 在语法上,很容易使用不可变变量,并且鼓励使用它们
  • 它在标准库中拥有丰富的不可变集合类
  • 这些集合类带有数十种函数方法:它们不会改变集合,而是返回数据的更新副本

一种面向对象语言

Scala 是一种面向对象编程 (OOP) 语言。每个值都是一个类的实例,每个“运算符”都是一个方法。

在 Scala 中,所有类型都继承自顶级类Any,它的直接子类是AnyVal值类型,例如IntBoolean)和AnyRef引用类型,如 Java 中)。这意味着 Java 中基本类型和装箱类型(例如intInteger)之间的区别在 Scala 中不存在。装箱和拆箱对用户来说是完全透明的。

支持 FP/OOP 融合

Scala 的本质是在类型化设置中融合函数式编程和面向对象编程

  • 逻辑函数
  • 模块化对象

正如 Martin Odersky 所述,“Scala 的设计旨在表明,融合函数式编程和面向对象编程是可行且实用的。”

术语推断,更加清晰

继 Haskell 之后,Scala 成为第二种拥有某种形式的隐式的流行语言。在 Scala 3 中,这些概念已经过彻底的重新思考,并得到了更清晰的实现。

核心思想是术语推断:给定一个类型,编译器会综合一个具有该类型的“规范”术语。在 Scala 中,上下文参数直接导致一个推断出的参数术语,该术语也可以显式写出来。

此概念的用例包括实现 类型类、建立上下文、依赖注入、表达功能、计算新类型以及证明它们之间的关系。

Scala 3 使这一过程比以往任何时候都更加清晰。请在 参考文档 中了解上下文抽象。

客户端和服务器

Scala 代码在 Java 虚拟机 (JVM) 上运行,因此你可以获得其所有优势

  • 安全性
  • 性能
  • 内存管理
  • 可移植性和平台独立性
  • 能够使用大量现有的 Java 和 JVM 库

除了在 JVM 上运行之外,Scala 还可以在浏览器中使用 Scala.js(以及开源第三方工具来集成流行的 JavaScript 库)运行,并且可以使用 Scala Native 和 GraalVM 构建本机可执行文件。

无缝的 Java 交互

你可以在 Scala 应用程序中使用 Java 类和库,你可以在 Java 应用程序中使用 Scala 代码。关于第二点,大型库(如 AkkaPlay Framework)是用 Scala 编写的,可以在 Java 应用程序中使用。

关于第一点,Java 类和库每天都在 Scala 应用程序中使用。例如,在 Scala 中,你可以使用 Java BufferedReaderFileReader 读取文件

import java.io.*
val br = BufferedReader(FileReader(filename))
// read the file with `br` ...

在 Scala 中使用 Java 代码通常是无缝的。

Java 集合也可以在 Scala 中使用,如果你想使用 Scala 丰富的集合类方法,只需几行代码即可转换它们

import scala.jdk.CollectionConverters.*
val scalaList: Seq[Integer] = JavaClass.getJavaList().asScala.toSeq

丰富的库

正如你将在本页的第三部分中看到的那样,Scala 库和框架(如这些库和框架)已被编写为支持繁忙的网站并处理海量数据集

  1. Play Framework 是一款轻量级、无状态、对开发人员友好、对 Web 友好的架构,用于创建高度可扩展的应用程序
  2. Apache Spark 是一款用于大数据处理的统一分析引擎,内置了用于流处理、SQL、机器学习和图形处理的模块

Awesome Scala 列表 展示了数十种其他开源工具,开发人员已创建这些工具来构建 Scala 应用程序。

除了服务器端编程之外,Scala.js 是编写 JavaScript 的强类型替代品,它包含开源第三方库,其中包括与 Facebook 的 React 库、jQuery 等集成的工具。

低级语言特性

上一部分介绍了 Scala 的高级功能,有趣的是,值得注意的是,在高级别上,你可以对 Scala 2 和 Scala 3 做出相同的陈述。十年前,Scala 以强大的理想功能为基础,正如你将在本部分中看到的那样,这些好处已通过 Scala 3 得到改进。

从细节的“海平面”视图来看,即程序员每天使用的语言功能,Scala 3 比 Scala 2 具有显着优势

  • 使用枚举更简洁地创建代数数据类型 (ADT) 的能力
  • 更简洁易读的语法
    • “安静”控制结构语法更易于阅读
    • 可选大括号
      • 代码中的符号更少,视觉噪音更少,从而更易于阅读
    • 在创建类实例时通常不再需要 new 关键字
    • 包对象的正式性已被更简单的“顶级”定义所取代
  • 更清晰的语法
    • 已删除 implicit 关键字的多种不同用法;这些用法已被更明显的关键字替换,例如 givenusingextension,重点关注意图而不是机制(有关详细信息,请参阅 Givens 部分)
    • 扩展方法 使用更清晰、更简单的机制替换隐式类
    • 为类添加 open 修饰符,使开发人员有意声明一个类可以修改,从而限制代码库的临时扩展
    • 多重相等性 排除了使用 ==!= 进行无意义的比较(即,尝试将 PersonPlanet 进行比较)
    • 宏的实现变得更加容易
    • 联合和交集提供了一种灵活的方法来建模类型
    • 特征参数替换并简化了早期初始化程序
    • 不透明类型别名替换了大多数值类的用法,同时保证不存在装箱
    • 导出子句提供了一种简单且通用的方式来表达聚合,它可以替换以前从类继承的包对象的立面模式
    • 过程语法已被删除,varargs 语法已被更改,这两者都是为了使语言更一致
    • @infix 注释使您希望如何应用方法变得显而易见
    • @targetName 方法注释为该方法定义了一个备用名称,改进了 Java 互操作性,并允许您为符号运算符提供别名

在这里展示所有这些功能将占用太多空间,但请按照上面项目中的链接查看这些功能的实际操作。所有这些功能都在 概述文档 中的新增已更改已删除功能页面中进行了详细讨论。

Scala 生态系统

Scala 拥有一个充满活力的生态系统,其中包含满足各种需求的库和框架。 “Awesome Scala” 列表 提供了数百个可供 Scala 开发人员使用的开源项目列表,而 Scaladex 提供了一个可搜索的 Scala 库索引。下面列出了一些更著名的库。

Web 开发

  • Play Framework 遵循 Ruby on Rails 模型,成为一种轻量级、无状态、对开发人员友好、对 Web 友好的架构,适用于高度可扩展的应用程序
  • Scalatra 是一个受 Sinatra 启发的微型、高性能、异步 Web 框架
  • Finatra 是建立在 TwitterServer 和 Finagle 之上的 Scala 服务
  • Scala.js 是 JavaScript 的强类型替代品,它提供了一种更安全的方法来构建健壮的前端 Web 应用程序
  • ScalaJs-React 将 Facebook 的 React 库提升到 Scala.js 中,并努力使其尽可能类型安全且对 Scala 友好

HTTP(S) 库

JSON 库

序列化

科学和数据分析

大数据

人工智能、机器学习

函数式编程和函数式反应式编程

FP

函数式反应式编程 (FRP)

构建工具

摘要

正如本页所示,Scala 拥有许多出色的编程语言特性,既有高级特性,也有日常编程级特性,还通过其开发人员生态系统提供特性。

本页的贡献者