Scala中有如下四种定义:字面量、值、变量和类型
- 字面量(literal):直接出现在源代码中的数据,如数字5、字母'a'和文本"hello world"
- 值(value):不可变的、有类型的存储单元。可以在定义值时为它指定数据,不过不允许重新赋值。
- 变量(variable):可变的、有类型的存储单元。可以在定义变量时指定数据,可以在任何时间重新赋值。
- 类型(type):所处理数据的种类(kind),这是对数据的一个定义或分类。Scala中所有数据都对应一个特定类型,所有Scala类型都定义为包含方法的类,这些方法将用来处理这些数据。
1.值
值是不可变的、有类型的存储单元。可以使用val关键字定义一个新值。
val a: Int = 1
值要有名和所赋的数据,不要求有显式的类型。如果未指定类型,Scala编译器会根据所赋数据来推导其类型。这个过程称为类型推导(type inference)。
2.变量
变量是动态、可变而且可赋值的。
在Scala中,按惯例,值优先于变量,这是因为值可以为代码带来稳定性和可预测性。
使用var关键字利用给定名字、类型和赋值来定义一个变量。
var x = 5
3.类型
Scala包含数值类型(例如Int和Double)和非数值类型(例如String)。
1.数值数据类型
image.png Scala支持根据类型等级自动将数字从一种类型转换到另一种类型。Byte类型等级最低,可以转换为任何其他类型。
Scala不允许从较高等级类型自动转换到较低等级类型。
可以使用toType方法完成类型间的转换,所有数值类型都有这样一个方法。
val l: Long = 20
val i: Int = l.toInt
除了使用显式类型,还有一种方法是使用Scala的字面量类型记法,直接指定字面量数据的类型。
image.png
2.字符串
val hello = "Hello World"
使用==运算符比较两个String值。与Java不同,==会检查真正的相等性,而不是对象引用相等性。
可以用三引号创建多行String。
val greeting = """hello
| world"""
字符串内插
要在一个String中加入值或变量,可以利用字符串内插,采用这种模式可以识别和解析外部值和变量名。记法是在字符串的第一个双引号前加一个"s"前缀,然后使用美元符($)指示外部数据的引用(可以有可选的大括号)。
val approx = 355/113f
println(s"Pi, using 355/113, is about $approx.")
如果引用中有非字符(如算式),或者引用于周围文本无法区分,需要使用大括号。
println(s"Fish n chips n vinegar, ${"pepper "*3} salt")
字符串内插的替代格式是使用printf记法,想要控制数据格式化时,如字符个数或小数值的显式,这种记法非常有用。要使用prinf记法,需要把前缀改为"f",然后将printf记法紧跟在引用后面。
val item = "apple"
println(f"I wrote a new $item%.3s today")
3.Scala类型概述
Scala的所有类型,从数字到字符串以及集合,都属于一个类型层次体系。你在Scala中定义的每一个类也会自动归入这个层次体系。
image.png
空心三角箭头指示超类型,下方带多个箭头的类型指示它们是这个系统中所有类型(包括自己定义的类)的子类型。
下表列出了途中提到的特定类型:
image.png
Any、AnyVal和AnyRef类型是Scala类层次体系的根。Any是绝对的根,所有其他类型都由它的两个子类型(AnyVal和AnyRef)派生。扩展AnyVal的类型称为值类型(value types),因为它们是用来表示数据的核心值。这包括所有数值类型,以及Char、Boolean和Unit。访问AnyVal类型与访问其他类型类似,不过可以在运行时作为对象在堆中分配内存,也可以作为JVM基本类型值在栈中分配内存。所有其他类型都以AnyRef作为根,只能作为对象在堆中分配内存。“Ref”指示它们是引用类型,可以通过一个内存引用来访问。
层次体系最下面是Nothing和Null类型。Nothing是所有其他类型的一个子类型,它的存在只是要为那些影响程序流的操作提供一个兼容的返回类型。
Null是所有AnyRef类型的一个子类型,它的存在是为了给关键字null提供一个类型。一般来讲,Scala的语法更优先使用实际类型和实例而不是保留字。
在Boolean类型中,&&和||有短路特性,如果第一个参数足以得出结论,它们就不再去计算第二个参数。操作符&和|则会在返回结果之前对两个参数都进行检查。
Scala不支持其他类型到Boolean的自动转换。
Unit类型与其他核心类型不同,它并不是一个指示数据的类型,而是指示没有数据。类似void关键字。Unit类型在Scala中作为不返回任何结果的函数或表达式的返回类型。
Unit字面量是一对空的小括号()。
类型操作
以下为常用类型操作:
image.png
4.元组
元组(tuple)是一个包含两个或多个值的有序容器,所有这些值可以由不同类型。关系数据库表中的一行可以认为是一个元组。不过,不同于列表和数组,没有办法迭代处理一个元组中的元素。元组的作用只是作为多个值的容器。
创建元组时,值之间要用逗号分隔,并用一对小括号包围。
val info = (5, "Korben", true)
可以根据元组的索引(从1开始)访问单个元素。
要创建一个大小为2的元组,另一种形式是利用关系操作符(->),这是一种表示元组中键值对的快捷方式:
val red = "red" -> "0xff0000"
网友评论