术语表来自 Scala 的权威书籍,Scala 编程。
-
代数数据类型
通过提供多个备选方案来定义的一种类型,每个备选方案都有自己的构造函数。它通常带有通过模式匹配分解类型的方法。该概念在规范语言和函数式编程语言中找到。代数数据类型可以用 case 类在 Scala 中模拟。
-
备选方案
匹配表达式的分支。它的形式为“
case
模式 => 表达式。”备选方案的另一个名称是case。 -
注释
注释出现在源代码中,并附加到语法的一部分。注释是计算机可处理的,因此你可以使用它们有效地为 Scala 添加扩展。
-
匿名类
匿名类是由 Scala 编译器从 new 表达式生成的合成子类,其中类或特征名称后跟大括号。大括号包含匿名子类的正文,该正文可能为空。但是,如果 new 后面的名称引用包含抽象成员的特征或类,则必须在定义匿名子类正文的大括号内使其具体化。
-
匿名函数
函数字面量的另一个名称。
-
应用
可以将方法、函数或闭包应用于参数,这意味着在这些参数上调用它。
-
参数
调用函数时,会为该函数的每个参数传递一个参数。参数是引用参数的变量。参数是在调用时传递的对象。此外,应用程序可以采用(命令行)参数,这些参数显示在传递给单例对象的主方法的
Array[String]
中。 -
分配
可以将对象分配给变量。之后,变量将引用该对象。
-
辅助构造函数
在类定义的花括号内定义的额外构造函数,看起来像名为
this
的方法定义,但没有结果类型。 -
块
一个或多个用花括号括起来的表达式和声明。当块求值时,其所有表达式和声明将按顺序处理,然后块返回最后一个表达式的值作为其自身的值。块通常用作函数、for 表达式、
while
循环以及希望将多条语句组合在一起的任何其他位置的主体。更正式地说,块是一种封装结构,你只能看到副作用和结果值。因此,定义类或对象的花括号不形成块,因为从外部可以看到该花括号内定义的字段和方法。这样的花括号形成一个模板。 -
绑定变量
表达式的绑定变量是在表达式内部同时使用和定义的变量。例如,在函数字面量表达式
(x: Int) => (x, y)
中,变量x
和y
都被使用,但只有x
被绑定,因为它在表达式中被定义为Int
和表达式描述的函数的唯一参数。 -
按名称传递的参数
在参数类型前用
=>
标记的参数,例如(x: => Int)
。与按名称传递的参数对应的参数不是在调用方法之前求值,而是在方法中按名称引用参数时每次求值。如果参数不是按名称传递的,则按值传递。 -
按值传递的参数
一个参数,其参数类型前面没有标记
=>
,例如(x: Int)
。与按值参数相对应,在调用方法之前对参数进行评估。按值参数与按名称参数形成对比。 -
类
使用
class
关键字定义,类 可以是抽象的或具体的,并且在实例化时可以用类型和值进行参数化。在new Array[String](2)
中,要实例化的类是Array
,而结果值的类型是Array[String]
。接受类型参数的类称为类型构造函数。类型也可以具有类,如下所示:类型Array[String]
的类是Array
。 -
闭包
一个函数对象,它捕获自由变量,并被认为“封闭”在创建时可见的变量中。
-
伴生类
一个与在同一源文件中定义的单例对象同名的类。该类是单例对象的伴生类。
-
伴生对象
一个与在同一源文件中定义的类同名的单例对象。伴生对象和类可以访问彼此的私有成员。此外,在伴生对象中定义的任何隐式转换都将在类被使用的任何地方处于作用域中。
-
逆变
可以通过在类型参数前加上减号 (-) 来将逆变注释应用于类或特征的类型参数。然后,该类或特征与注释类型参数逆变地进行子类型化——与类型注释参数相反的方向。例如,
Function1
在其第一个类型参数中是逆变的,因此Function1[Any, Any]
是Function1[String, Any]
的子类型。 -
协变
可以通过在类型参数前加上加号 (+) 来将协变注释应用于类或特征的类型参数。然后,该类或特征与注释类型参数协变地进行子类型化——与类型注释参数相同的方向。例如,
List
在其类型参数中是协变的,因此List[String]
是List[Any]
的子类型。 -
柯里化
编写具有多个参数列表的函数的一种方法。例如
def f(x: Int)(y: Int)
是一个具有两个参数列表的柯里化函数。通过传递多个参数列表来应用柯里化函数,如下所示:f(3)(4)
。但是,也可以编写柯里化函数的部分应用,例如f(3)
。 -
声明
你可以声明一个抽象字段、方法或类型,它为实体提供一个名称,但不提供一个实现。声明和定义之间的主要区别在于:定义为命名的实体建立一个实现,而声明则不建立。
-
定义
在 Scala 程序中定义某物是指为其提供一个名称和一个实现。你可以定义类、特质、单例对象、字段、方法、局部函数、局部变量等。因为定义总是涉及某种实现,所以抽象成员是声明的,而不是定义的。
-
直接子类
一个类是其直接超类的直接子类。
-
直接超类
一个类或特质直接派生的类,在其继承层次结构中位于其上方的最近类。如果一个类
Parent
在一个类Child
的可选 extends 子句中被提及,那么Parent
就是Child
的直接超类。如果一个特质在Child
的 extends 子句中被提及,那么该特质的直接超类就是Child
的直接超类。如果Child
没有 extends 子句,那么AnyRef
就是Child
的直接超类。如果一个类的直接超类采用类型参数,例如类Child
扩展Parent[String]
,那么Child
的直接超类仍然是Parent
,而不是Parent[String]
。另一方面,Parent[String]
将是Child
的直接超类型。有关类和类型之间区别的更多讨论,请参见 超类型。 -
相等
在不加限定的情况下使用时,相等是值之间由
==
表示的关系。另请参见 引用相等。 -
存在类型
存在类型包含对未知类型变量的引用。例如,
Array[T] forSome { type T }
是一个存在类型。它是一个T
数组,其中T
是某种完全未知的类型。对T
的所有假设都是它确实存在。这个假设很弱,但它至少意味着Array[T] forSome { type T }
确实是一个数组,而不是香蕉。 -
表达式
产生结果的任何 Scala 代码片段。你还可以说一个表达式求值为一个结果或产生一个值。
-
筛选器
在 for 表达式 中,
if
后跟一个布尔表达式。在for(i <- 1 to 10; if i % 2 == 0)
中,筛选器是“if i % 2 == 0
”。if
右侧的值是 筛选器表达式。也称为保护器。 -
筛选器表达式
筛选器表达式是在 for 表达式 中的
if
后面的布尔表达式。在for( i <- 1 to 10 ; if i % 2 == 0)
中,筛选器表达式是“i % 2 == 0
”。 -
一等函数
Scala 支持一等函数,这意味着你可以用函数字面语法表示函数,即
(x: Int) => x + 1
,并且函数可以用对象表示,这些对象称为 函数值。 -
for 推导
用于理解是一种 for 表达式,可创建新集合。对于
for
理解的每次迭代,yield 子句定义新集合的一个元素。例如,for (i <- (0 until 2); j <- (2 until 4)) yield (i, j)
返回集合Vector((0,2), (0,3), (1,2), (1,3))
。 -
for 表达式
for 表达式要么是 for 循环(迭代一个或多个集合),要么是 for 理解(根据一个或多个集合的元素构建新集合)。
for
表达式由 生成器、过滤器、变量定义以及(在 for 理解 的情况下)yield 子句构成。 -
for 循环
for 循环是一种 for 表达式,可循环一个或多个集合。由于
for
循环返回单位,因此它们通常产生副作用。例如,for (i <- 0 until 100) println(i)
打印数字 0 到 99。 -
自由变量
表达式的自由变量是在表达式中使用但未在表达式中定义的变量。例如,在函数文字表达式
(x: Int) => (x, y)
中,变量x
和y
都被使用,但只有y
是自由变量,因为它未在表达式中定义。 -
函数
函数可以使用参数列表调用,以产生结果。函数具有参数列表、主体和结果类型。作为类、特征或单例对象成员的函数称为方法。在其他函数内部定义的函数称为局部函数。结果类型为
Unit
的函数称为过程。源代码中的匿名函数称为函数字面量。在运行时,函数字面量会被实例化为称为函数值的对象。 -
函数字面量
Scala 源代码中没有名称的函数,使用函数字面量语法指定。例如,
(x: Int, y: Int) => x + y
。 -
函数值
可以像任何其他函数一样调用的函数对象。函数值的类扩展自包
scala
中的FunctionN
特征之一(例如,Function0
、Function1
),并且通常通过函数字面量语法在源代码中表示。当调用其 apply 方法时,函数值会被“调用”。捕获自由变量的函数值是闭包。 -
函数式风格
函数式风格的编程强调函数和评估结果,并且不强调操作发生的顺序。该风格的特点是将函数值传递到循环方法、不可变数据、无副作用的方法中。它是 Haskell 和 Erlang 等语言的主要范例,并且与命令式风格形成对比。
-
生成器
生成器定义一个命名的 val,并在for 表达式中为其分配一系列值。例如,在
for(i <- 1 to 10)
中,生成器为“i <- 1 to 10
”。<-
右侧的值是生成器表达式。 -
生成器表达式
生成器表达式在for 表达式中生成一系列值。例如,在
for(i <- 1 to 10)
中,生成器表达式为“1 to 10
”。 -
泛型类
采用类型参数的类。例如,因为
scala.List
采用类型参数,所以scala.List
是泛型类。 -
泛型特征
采用类型参数的特征。例如,因为特征
scala.collection.Set
采用类型参数,所以它是一个泛型特征。 -
保护
参见filter。
-
辅助函数
其目的是为附近的一个或多个其他函数提供服务的函数。辅助函数通常作为局部函数实现。
-
辅助方法
属于类的辅助函数。辅助方法通常是私有的。
-
不可变
如果对象的值在创建后不能以任何对客户端可见的方式更改,则该对象是不可变的。对象可能不可变,也可能可变。
-
命令式风格
编程的命令式风格强调仔细对操作进行排序,以便它们的效应按正确的顺序发生。该风格的特点是使用循环进行迭代、就地改变数据以及具有副作用的方法。它是 C、C++、C# 和 Java 等语言的主要范例,与函数式风格形成对比。
-
初始化
在 Scala 源代码中定义变量时,必须使用对象对其进行初始化。
-
实例
实例或类实例是一个对象,它是一个仅在运行时存在的概念。
-
实例化
实例化类是指从类中创建一个新对象,此操作仅在运行时发生。
-
不变量
不变量以两种方式使用。它可以表示当数据结构形成良好时始终成立的属性。例如,有序二叉树的不变量是,如果每个节点都有一个右子节点,则该节点在右子节点之前排序。不变量有时也用作非变量的同义词:“类
Array
在其类型参数中是不变量的”。 -
调用
可以在参数上调用方法、函数或闭包,这意味着其主体将使用指定的参数执行。
-
JVM
JVM是 Java 虚拟机或运行时,它承载运行的 Scala 程序。
-
字面量
1
、"One"
和(x: Int) => x + 1
是字面量的示例。字面量是描述对象的简写方式,其中简写完全反映了创建的对象的结构。 -
局部函数
局部函数是在块内定义的
def
。相比之下,作为类、特质或单例对象的成员定义的def
称为方法。 -
局部变量
局部变量是块内定义的
val
或var
。虽然类似于 局部变量,但函数参数不被称作局部变量,而仅仅被称为参数或“变量”,不带“局部”。 -
成员
成员是类、特质或单例对象的模板中的任何命名元素。可以通过其所有者的名称、一个点及其简单名称来访问成员。例如,在类中定义的顶级字段和方法是该类的成员。在类内定义的特质是其封闭类的成员。在类中使用 type 关键字定义的类型是该类的成员。类是其定义所在的包的成员。相比之下,局部变量或局部函数不是其周围块的成员。
-
消息
Actor 通过互相发送消息进行通信。发送消息不会中断接收者正在执行的操作。接收者可以等到其完成当前活动并重新建立其不变量后。
-
元编程
元编程软件是其输入本身就是软件的软件。编译器是元程序,像
scaladoc
这样的工具也是元程序。为了对注释执行任何操作,需要元编程软件。 -
方法
方法是某个类、特质或单例对象成员的函数。
-
混入
当特质在混入组合中使用时,称为混入。换句话说,在“
trait Hat
”中,Hat
只是一个特质,但在“new Cat extends AnyRef with Hat
”中,Hat
可以称为混入。用作动词时,“混入”是两个词。例如,你可以将特质混入类或其他特质中。 -
混入组合
将特质混入类或其他特质的过程。混入组合不同于传统的多重继承,因为超引用类型的类型在定义特质时未知,而是在每次将特质混入类或其他特质时重新确定。
-
修饰符
一种以某种方式限定类、特征、字段或方法定义的关键字。例如,
private
修饰符表示正在定义的类、特征、字段或方法是私有的。 -
多个定义
如果使用语法
val v1, v2, v3 = exp
,则可以在多个定义中分配相同的表达式。 -
不变体
类或特征的类型参数默认情况下为不变体。然后,当该参数更改时,类或特征不会进行子类型化。例如,由于类
Array
在其类型参数中是不变的,因此Array[String]
既不是Array[Any]
的子类型也不是超类型。 -
操作
在 Scala 中,每个操作都是一个方法调用。方法可以在运算符表示法中调用,例如
b + 2
,并且在该表示法中,+
是一个运算符。 -
参数
函数可以采用零到多个参数。每个参数都有一个名称和一个类型。参数和自变量之间的区别在于,自变量是指在调用函数时传递的实际对象。参数是引用那些传递的自变量的变量。
-
无参数函数
不带任何空括号定义的函数,不采用任何参数。无参数函数的调用可能不提供括号。这支持统一访问原则,该原则允许将
def
更改为val
,而无需更改客户端代码。 -
无参数方法
无参数方法是无参数函数,它是类、特征或单例对象的成员。
-
参数化字段
作为类参数定义的字段。
-
部分应用函数
在表达式中使用且缺少一些自变量的函数。例如,如果函数
f
的类型为Int => Int => Int
,则f
和f(1)
是部分应用函数。 -
路径相关类型
类似于
swiss.cow.Food
的类型。swiss.cow
部分是形成对对象的引用的路径。该类型的含义取决于用于访问它的路径。例如,类型swiss.cow.Food
和fish.Food
是不同的类型。 -
模式
在
match
表达式替代项中,模式遵循每个case
关键字,并位于模式保护或=>
符号之前。 -
模式保护
在
match
表达式备选方案中,模式保护符可以紧跟 模式。例如,在“case x if x % 2 == 0 => x + 1
”中,模式保护符是“if x % 2 == 0
”。只有当模式匹配且模式保护符产生 true 时,才会选择带有模式保护符的 case。 -
谓词
谓词是具有
Boolean
结果类型的函数。 -
主构造函数
类的主要构造函数,如果需要,它将调用超类构造函数,将字段初始化为传递的值,并执行在大括号中定义的任何顶级代码。仅为未传递给超类构造函数的值参数初始化字段,但类主体中未使用的任何字段除外,因此可以对其进行优化。
-
过程
过程是结果类型为
Unit
的函数,因此仅针对其副作用执行。 -
可重新赋值
变量可能可重新赋值或不可重新赋值。
var
可重新赋值,而val
不可重新赋值。 -
递归
如果函数调用自身,则该函数是递归的。如果函数调用自身的位置是函数的最后一个表达式,则该函数是 尾递归。
-
引用
引用是 Java 指针的抽象,它唯一标识驻留在 JVM 堆上的对象。引用类型变量持有对对象的引用,因为引用类型(
AnyRef
的实例)是作为驻留在 JVM 堆上的 Java 对象实现的。相比之下,值类型变量有时可能持有引用(指向装箱包装类型),有时可能不持有引用(当对象表示为基本值时)。一般来说,Scala 变量 引用 对象。术语“引用”比“持有引用”更抽象。如果类型为scala.Int
的变量当前表示为基本 Javaint
值,则该变量仍引用Int
对象,但没有涉及引用。 -
引用相等
引用相等意味着两个引用标识完全相同的 Java 对象。引用相等只能通过在
AnyRef
中调用eq
来确定(仅适用于引用类型)。(在 Java 程序中,可以使用==
在 Java 引用类型 上确定引用相等。) -
引用类型
引用类型是
AnyRef
的子类。引用类型的实例在运行时始终驻留在 JVM 的堆上。 -
引用透明性
独立于时间上下文且没有副作用的函数的属性。对于特定输入,可以将引用透明函数的调用替换为其结果,而不会更改程序语义。
-
引用
正在运行的 Scala 程序中的变量始终引用某个对象。即使该变量被分配给
null
,它在概念上也引用Null
对象。在运行时,对象可以通过 Java 对象或原始类型的某个值来实现,但 Scala 允许程序员在更高的抽象级别上思考他们的代码,因为他们想象代码正在运行。另请参见 引用。 -
细化类型
通过在花括号内提供带有若干成员的基本类型而形成的类型。花括号中的成员细化基本类型中存在的类型。例如,“吃草的动物”的类型是
Animal { type SuitableFood = Grass }
。 -
结果
Scala 程序中的表达式产生结果。Scala 中每个表达式的结果都是一个对象。
-
结果类型
方法的结果类型是调用该方法所产生的值的类型。(在 Java 中,此概念称为返回类型。)
-
返回
Scala 程序中的函数返回一个值。你可以将此值称为函数的 结果。你还可以说函数导致该值。Scala 中每个函数的结果都是一个对象。
-
运行时
托管正在运行的 Scala 程序的 Java 虚拟机或 JVM。运行时既包括由 Java 虚拟机规范定义的虚拟机,也包括 Java API 和标准 Scala API 的运行时库。短语 at run time(run 和 time 之间有空格)表示程序正在运行时,与编译时形成对比。
-
运行时类型
对象在运行时的类型。相比之下,静态类型是表达式在编译时的类型。大多数运行时类型只是没有类型参数的简单类。例如,
"Hi"
的运行时类型是String
,(x: Int) => x + 1
的运行时类型是Function1
。可以使用isInstanceOf
测试运行时类型。 -
脚本
一个包含顶级定义和语句的文件,可以使用
scala
直接运行,而无需显式编译。一个脚本必须以一个表达式结尾,而不是一个定义。 -
选择器
在
match
表达式中匹配的值。例如,在 “s match { case _ => }
” 中,选择器是s
。 -
自身类型
一个特质的自身类型是
this
的假定类型,接收器,在特质中使用。任何混入特质的具体类都必须确保其类型符合特质的自身类型。自身类型最常见的用途是将一个大类划分为几个特质(如 Scala 编程 第 29 章所述)。 -
半结构化数据
XML 数据是半结构化的。它比平面二进制文件或文本文件更具结构化,但它没有编程语言数据结构的完整结构。
-
序列化
您可以将一个对象序列化为一个字节流,然后将其保存到文件或通过网络传输。您以后可以在不同的计算机上反序列化字节流,并获得一个与原始序列化对象相同的对象。
-
阴影
一个局部变量的新声明阴影了封闭作用域中同名的变量。
-
签名
签名是 类型签名 的简称。
-
单例对象
使用 object 关键字定义的对象。每个单例对象只有一个实例。一个与类同名的单例对象,并且在与该类相同的源文件中定义,是该类的 伴生对象。该类是它的 伴生类。没有伴生类的单例对象是 独立对象。
-
独立对象
-
语句
一个表达式、定义或导入,即,可以在 Scala 源代码中的模板或块中使用的内容。
-
静态类型
参见 类型。
-
结构类型
一种 细化类型,其中细化是针对基本类型中不存在的成员。例如,
{ def close(): Unit }
是一个结构类型,因为基本类型是AnyRef
,而AnyRef
没有名为close
的成员。 -
子类
-
子特征
一个特征是其所有超特征的子特征。
-
子类型
Scala 编译器允许使用类型的任何子类型来代替在任何需要该类型的地方。对于不采用任何类型参数的类和特征,子类型关系反映了子类关系。例如,如果类
Cat
是抽象类Animal
的子类,并且两者都不采用类型参数,那么类型Cat
是类型Animal
的子类型。同样,如果特征Apple
是特征Fruit
的子特征,并且两者都不采用类型参数,那么类型Apple
是类型Fruit
的子类型。但是,对于采用类型参数的类和特征,变异性就会发挥作用。例如,由于抽象类List
被声明为在其唯一类型参数中协变(即List
被声明为List[+A]
),因此List[Cat]
是List[Animal]
的子类型,而List[Apple]
是List[Fruit]
的子类型。即使这些类型的每个类的类都是List
,这些子类型关系也存在。相比之下,由于Set
未被声明为在其类型参数中协变(即Set
被声明为Set[A]
,没有加号),因此Set[Cat]
不是Set[Animal]
的子类型。子类型应正确实现其超类型的契约,以便应用里氏替换原则,但编译器仅在类型检查级别验证此属性。 -
超类
类的超类包括其直接超类、其直接超类的直接超类,依此类推,一直到
Any
。 -
超特征
一个类或特征的超特征(如果有的话)包括直接混入到该类或特征或其任何超类中的所有特征,以及这些特征的任何超特征。
-
超类型
一个类型是其所有子类型的超类型。
-
合成类
合成类是由编译器自动生成的,而不是由程序员手动编写的。
-
尾递归
如果一个函数调用自身是函数的最后一个操作,那么这个函数就是尾递归。
-
目标类型化
目标类型化是一种类型推断形式,它考虑到了预期的类型。例如,在
nums.filter((x) => x > 0)
中,Scala 编译器将x
的类型推断为nums
的元素类型,因为filter
方法对nums
的每个元素调用该函数。 -
模板
模板是类、特征或单例对象定义的主体。它定义了类、特征或对象的类型签名、行为和初始状态。
-
特征
特征(使用
trait
关键字定义)类似于抽象类,它不能采用任何值参数,并且可以通过称为混合组合的过程“混入”到类或其他特征中。当一个特征被混入到一个类或特征中时,它被称为混合。特征可以用一个或多个类型进行参数化。当使用类型进行参数化时,特征会构造一个类型。例如,Set
是一个采用单个类型参数的特征,而Set[Int]
是一个类型。此外,Set
被称为类型Set[Int]
的“特征”。 -
类型
Scala 程序中的每个变量和表达式都有一个在编译时已知的类型。类型限制了变量在运行时可以引用的可能值,或表达式可以生成的值。如果需要将变量或表达式的类型与对象的运行时类型区分开来,也可以将其称为静态类型。换句话说,“类型”本身表示静态类型。类型不同于类,因为采用类型参数的类可以构造许多类型。例如,
List
是一个类,但不是一个类型。List[T]
是一个带有自由类型参数的类型。List[Int]
和List[String]
也是类型(称为基础类型,因为它们没有自由类型参数)。类型可以有“类”或“特征”。例如,类型List[Int]
的类是List
。类型Set[String]
的特征是Set
。 -
类型约束
一些注释是类型约束,这意味着它们对类型包含的值添加了额外的限制或约束。例如,
@positive
可以是对类型Int
的类型约束,将 32 位整数的类型限制为正整数。类型约束不会被标准 Scala 编译器检查,而必须由其他工具或编译器插件检查。 -
类型构造器
采用类型参数的类或特征。
-
类型参数
泛型类或泛型方法的参数,必须由类型填充。例如,类
List
被定义为“class List[T] { . . .
”,并且方法identity
(对象Predef
的成员)被定义为“def identity[T](x:T) = x
”。在这两种情况下,T
都是类型参数。 -
类型签名
方法的类型签名包括其名称、参数(如果有)的数量、顺序和类型,以及其结果类型。类、特质或单例对象的类型签名包括其名称、其所有成员和构造函数的类型签名,以及其声明的继承和混合关系。
-
统一访问原则
统一访问原则规定,变量和无参数函数应使用相同的语法进行访问。Scala 支持此原则,不允许在无参数函数的调用位置放置括号。因此,可以将无参数函数定义更改为
val
,或反之亦然,而不会影响客户端代码。 -
不可达
在 Scala 级别,对象可以变成不可达,此时它们占用的内存可以被运行时回收。不可达并不一定意味着未引用。引用类型(
AnyRef
的实例)作为驻留在 JVM 堆上的对象实现。当引用类型的实例变为不可达时,它确实变为未引用,并且可用于垃圾回收。值类型(AnyVal
的实例)作为基本类型值和 Java 包装器类型(例如java.lang.Integer
)的实例实现,它们驻留在堆上。值类型实例可以在引用它们的变量的整个生命周期内进行装箱(从基本值转换为包装器对象)和拆箱(从包装器对象转换为基本值)。如果当前在 JVM 堆上表示为包装器对象的某个值类型实例变为不可达,则它确实变为未引用,并且可用于垃圾回收。但是,如果当前表示为基本值的值类型变为不可达,则它不会变为未引用,因为它在此时不存在于 JVM 堆上的对象中。运行时可以回收不可达对象占用的内存,但是,例如,如果 Int 在运行时由基本 Java int 实现,该 int 占用执行方法的堆栈帧中的一些内存,那么当方法完成时堆栈帧弹出后,该对象的内存将被“回收”。引用类型的内存,例如Strings
,可能在它们变为不可达后被 JVM 的垃圾回收器回收。 -
未引用
参见 不可达。
-
值
Scala 中任何计算或表达式的结果都是值,并且在 Scala 中,每个值都是一个对象。术语值本质上表示内存中对象的映像(在 JVM 的堆或栈上)。
-
值类型
值类型是
AnyVal
的任何子类,例如Int
、Double
或Unit
。此术语在 Scala 源代码级别具有意义。在运行时,与 Java 基本类型相对应的值类型的实例可以用基本类型值或包装器类型的实例来实现,例如java.lang.Integer
。在值类型实例的生命周期中,运行时可以在基本类型和包装器类型之间来回转换它(即,对其进行装箱和拆箱)。 -
变量
引用对象的已命名实体。变量可以是
val
或var
。定义val
和var
时必须初始化,但只有var
可以稍后重新赋值以引用不同的对象。 -
协变
类或特质的类型参数可以使用协变注释标记,可以是 协变 (+) 或 逆变 (-)。此类协变注释指示子类型如何适用于泛型类或特质。例如,泛型类
List
在其类型参数中是协变的,因此List[String]
是List[Any]
的子类型。默认情况下,即,如果没有+
或-
注释,类型参数将是 不变 的。 -
生成
表达式可以生成结果。
yield
关键字指定 for 理解 的结果。