5.2 字面量
表5.1中列出的所有基础类型都可以用字面量(literal)来书写。字面量是在代码中直接写入常量值的一种方式。
Java程序员的快速通道
本节中展示的大部分字面量的用法与Java完全一致,如果你是Java高手,则可以安心地跳过本节的绝大部分内容。你需要读一读的是Scala原生字符串字面量(77页开始)及字符串插值(79页开始)。另外,Scala并不支持八进制字面量和以0开头的整数字面量,如031将无法通过编译[2]。
整数字面量
用于Int、Long、Short和Byte的整数字面量有两种形式:十进制的和十六进制的。整数字面量的不同开头表示了不同的进制。如果以0x或0X开头,则意味着这是十六进制的数,可以包含0到9,以及大写或小写的A到F表示的数字。例如:
需要注意的是,Scala的shell总是以十进制打印整数值,无论你使用哪种形式来初始化。因此编译器把用字面量0x00FF初始化的变量hex2显示为十进制的255。(当然,不必盲目相信我们说的,感受Scala的好方法是一边读一边在编译器中尝试这些语句。)如果字面量是以非0的数字开头的,且除此之外没有其他修饰,这个数就是十进制的。例如:
如果整数字面量以L或l结尾,它就是Long类型的,否则就是Int类型的。一些Long类型的整数字面量如下:
如果一个Int类型的字面量被赋值给一个类型为Short或Byte的变量,则该字面量会被当作Short或Byte类型,只要这个字面量的值在对应类型的合法取值区间即可。例如:
浮点数字面量
浮点数字面量由十进制的数字、可选的小数点(decimal point),以及后续一个可选的E或e开头的指数(exponent)组成。一些浮点数字面量如下:
需要注意的是,指数部分指的是对前一部分乘以10的多少次方。例如,1.2345e1等于1.2345乘以10的1次方,即12.345。如果浮点数字面量以F或f结尾,它就是Float类型的;否则它就是Double类型的。Double类型的浮点数字面量也可以以D或d结尾,但这是可选的。一些Float字面量如下:
如果要以Double来表示最后这个浮点数值,则可以采用下面(或其他)的形式:
更大的数值字面量
Scala 3包含了一个实验属性的功能特性,可以消除数值字面量的大小限制,用来初始化任意一种(数值)类型。你可以通过如下的引入语句来开启这个特性:
来自标准类库的两个示例如下:
字符字面量
字符字面量由一对单引号和中间的任意Unicode字符组成,例如:
除了显式地给出原字符,也可以用字符的Unicode码来表示。具体写法是\u加上Unicode码对应的4位的十六进制数字,例如:
事实上,这样的Unicode字符可以出现在Scala程序的任何位置。比如,可以像这样命名一个标识符(变量):
这个标识符的处理方法与BAD一样,也就是将上述Unicode码解开后的结果。通常来说,这样的标识符命名方法并不好,因为不易读。这样的语法规则的存在,本意是让包含非ASCII的Unicode字符的Scala源文件可以用ASCII表示。
最后,还有一些字符字面量是由特殊的转义序列来表示的,如表5.2所示。例如:
表5.2 特殊的转义序列
字符串字面量
字符串字面量由双引号引起来的字符组成:
双引号中字符的语法与字符字面量的一样。比如:
由于这个语法对那些包含大量转义序列或者跨多行的字符串而言比较别扭,因此Scala支持一种特殊的语法来表示原生字符串(raw string)。可以用3个双引号(""")开始并用3个双引号(""")结束来表示原生字符串。原生字符串内部可以包含任何字符,如换行符、单/双引号和其他特殊字符。当然,连续3个双引号的情况除外。例如,如下程序就是用原生字符串来打印一条消息:
不过,运行这段代码并不会产生与我们想要的完全一致的输出:
这里的问题是字符串第二行前面的空格被包含在了字符串里。为了处理这个常见的情况,可以对字符串调用stripMargin方法。具体做法是在每一行开始加一个管道符(|),然后对整个字符串调用stripMargin方法:
现在这段代码满足我们的要求了:
布尔值字面量
Boolean类型有两个字面量,即true和false:
关于字面量的内容就这些。从“字面”上讲[3],你已经是Scala的专家了。