Scala 编程(三)基本类型和操作
一些基本类型
值类型 |
范围 |
Byte |
8位有符号补码整数(-27~27-1) |
Short |
16位有符号补码整数(-215~215-1) |
Int |
32位有符号补码整数(-231~231-1) |
Long |
64位有符号补码整数(-263~263-1) |
Char |
16位无符号Unicode字符(0~216-1) |
String |
字符序列 |
Float |
32位IEEE754单精度浮点数 |
Double |
64位IEEE754单精度浮点数 |
Boolean |
true或false |
除了 String 归于 java.lang 包之外,其余所有的基本类型都是包 scala 的成员。
文本
所有在上述列出的基本类型都可以写成文本:literal。文本是直接在代码里写常量值的一种方式。
整数文本
类型 Int , Long , Short 和 Byte 的整数文本有三种格式:十进制,十六进制和八进制。整数文本的开头方式说明了数字的基。如果数开始于 0x 或 0X ,那它是十六进制(基于16),并且可能包含从 0 到 9 ,及大写或小写的从 A 到 F 的数字:
scala> val hex = 0x5
hex: Int = 5 scala> val hex = 0xcafebabe
hex: Int = -889275714
不论用什么形式的整数文本初始化, Scala 的 shell 始终打印输出基于 10 的整数值。因此解释器会把你用文本 0x00FF 初始化的 hex2 变量的值显示为十进制的255。
如果数开始于零,就是八进制的:
scala> val oct = 035 // (八进制35是十进制29)
oct: Int = 29 scala> val nov = 0777
nov: Int = 511 scala> val dec = 0321
dec: Int = 209
如果数开始于非零数字,并且没有被修饰过,就是十进制:
scala> val dec1 = 31
dec1: Int = 31 scala> val dec2 = 255
dec2: Int = 255 scala> val cec3 = 20
cec3: Int = 20
如果整数文本结束于 L 或者 l ,就是 Long 类型,否则就是 Int 类型:
scala> val prog = 0XAFEBABEL
prog: Long = 184466110 scala> val tower = 35L
tower: Long = 35 scala> val of = 31l
of: Long = 31
如果 Int 类型的文本被赋值给 Short 或者 Byte 类型的变量,文本就会被看作是能让文本值在那个类型有效范围内那么长的 Short 或者 Byte 类型:
scala> val little:Short = 367
little: Short = 367 scala> val littler:Byte = 38
littler: Byte = 38
浮点数文本
浮点数文本是由十进制数字,可选的小数点和可选的 E 或 e 及指数部分组成的:
scala> val big = 1.2345
big: Double = 1.2345 scala> val bigger = 1.2345e1
bigger: Double = 12.345 scala> val biggerStill = 123E45
biggerStill: Double = 1.23E47
如果浮点数文本以 F 或 f 结束,就是 Float 类型的,否则就是 Double 类型的。可选的, Double 浮点数文本也可以 D 或 d 结尾:
scala> val little = 1.2345F
little: Float = 1.2345 scala> val littleBigger = 3e5f
littleBigger: Float = 300000.0 scala> val anotherDouble = 3e5
anotherDouble: Double = 300000.0 scala> val yetAnother = 3e5D
yetAnother: Double = 300000.0
字符文本
字符文本可以是在单引号之间的任何 Unicode 字符:
scala> val a = 'A'
a: Char = A
除了在单引号之间显式地提供字符之外,还可以提供一个表示字符代码点的前缀反斜杠的八进制或者十六进制数字。八进制数必须在 '\0' 和 '\377' 之间。例如字母 A 的 Unicode 字符代码点是八进制101:
scala> val c = '\101'
c: Char = A
字符文本同样可以以前缀 \u 的四位十六进制数字的通用 Unicode 字符方式给出:
scala> val d = '\u0041'
d: Char = A scala> val f = '\u0044'
f: Char = D
这种 Unicode 字符可以出现在 Scala 程序的任何地方:
scala> val B\u0041\u0044 = 1
BAD: Int = 1
字串文本
字串文本由双引号(")环绕的字符组成:
scala> val hello = "hello"
hello: String = hello
引号内的字符语法与字符文本相同:
scala> val escapes = "\\\"\'"
escapes: String = \"'
Scala为原始字串:raw String 引入了一种特殊的语法:以同一行里的三个引号(""")开始和结束一条原始字串。内部的原始字串可以包含无论何种任意字符,包括新行,引号和特殊字符:
scala> println("""Welcome to Ultamix 3000.
| Type "HELP" for helo.""")
Welcome to Ultamix 3000.
Type "HELP" for helo.
原因是第二行前导的空格被包含在了字串里。字串类的stripMargin方法可以控制格式,使用的方式是把管道符号(|)放在每行前面,然后在整个字串上调用stripMargin:
scala> println("""|Welcome to Ultamix 3000.
| |Type "HELP" for help.""".stripMargin)
Welcome to Ultamix 3000.
Type "HELP" for help.
符号文本
符号文本被写成'<标识符>,这里<标识符>可以是任何字母或数字的标识符。这种文本被映射成预定义类 scala.Symbol 的实例。文本 'cymbal 将被编译器扩展为工厂方法调用: Symbol("cymbal") 。符号文本典型的应用场景是在动态类型语言中使用一个标识符。比方说,想要定义个更新数据库记录的方法:
scala> def updateRecordByName(r: Symbol, value: Any) {
| // code goes here
| }
updateRecordByName: (r: Symbol, value: Any)Unit
方法带了一个符号参数指明记录的字段名和一个字段应该更新进记录的值。在动态类型语言中,可以通过传入一个未声明的字段标识符给方法调用这个操作,但 Scala 里这样会编译不过:
scala> updateRecordByName(favoriteAlbum, "OK Computer")
<console>:12: error: not found: value favoriteAlbum
updateRecordByName(favoriteAlbum, "OK Computer")
基本同样简洁的替代方案是传递一个符号文本:
scala> updateRecordByName('favoriteAlbum, "OK Computer")
除了发现它的名字之外,没有太多能对符号做的事情:
scala> val s = 'aSymbol
s: Symbol = 'aSymbol scala> s.name
res7: String = aSymbol
符号是被拘禁:interned的。如果把同一个符号文本写两次,那么两个表达式将指向同一个Symbol对象。
布尔型文本
布尔类型有两个文本, true 和 false :
scala> val bool = true
bool: Boolean = true scala> val foole = false
foole: Boolean = false
操作符和方法
操作符标注不仅限于像 + 这种其他语言里看上去像操作符一样的东西。可以把任何方法都当作操作符来标注。例如,类 String 有一个方法 indexOf 带一个 Char 参数。 indexOf 方法搜索 String 里第一次出现的指定字符,并返回它的索引或 -1 。可以把 indexOf 当作中缀操作符使用:
scala> val s = "Hello, world!"
s: String = Hello, world! scala> s indexOf 'o' // Scala调用了s.indexOf(’o’)
res0: Int = 4
另外, String 提供一个重载的 indexOf 方法,带两个参数,分别是要搜索的字符和从哪个索引开始搜索,仍然可以用操作符标注的方式使用它,不过这些参数必须放在括号内:
scala> s indexOf ('o', 5) // Scala调用了s.indexOf(’o’, 5)
res1: Int = 8
Scala 里的操作符不是特殊的语言语法:任何方法都可以是操作符。使用方法的方式使它成为操作符。如果写成 s.indexOf('o') , indexOf 就不是操作符。如果写成 s indexOf 'o' ,那么 indexOf 就是操作符。
以上是中缀操作符的例子, Scala 还有另外两种操作符标注:前缀和后缀。前缀标注中,方法名被放在调用的对象之前,如 -7 里的 ‘-’,后缀标注中,方法放在对象之后,如 “7 toLong” 里的 “toLong”。
前缀和后缀操作符都是一元:unary的:它们仅带一个操作数。前缀方式中,操作数在操作符的右边。前缀操作符的例子有 -2.0 , !found 和 ~0xFF 。与中缀操作符一致,这些前缀操作符是在值类型对象上调用方法的简写方式。实际上方法名在操作符字符上前缀了“unary_”。例如,Scala会把表达式 -2.0 转换成方法调用“(2.0).unary_-”:
scala> -2.0 // Scala调用了(2.0).unary_-
res2: Double = -2.0 scala> (2.0).unary_-
res3: Double = -2.0
可以当作前缀操作符用的标识符只有 + , - , ! 和 ~ 。因此如果定义了名为 unary_! 的方法,就可以像 !p 这样在合适的类型值或变量上用前缀操作符方式调用这个方法。但是如果定义名为 unary_* 的方法,也没办法用成前缀操作符,因为 * 不是四种可以当作前缀操作符用的标识符之一。可以像平常那用调用它,如 p.unary_* ,但如果尝试像 *p 这么调用, Scala 就会把它理解为 *.p 。
后缀操作符是不用点或括号调用的不带任何参数的方法。 Scala 里如果方法带有副作用就加上括号,如 println() ,如果方法没有副作用就可以去掉括号,如 String 上调用的 toLowerCase :
scala> val s = "Hello, world!"
s: String = Hello, world! scala> s.toLowerCase
res4: String = hello, world! scala> s toLowerCase
res5: String = hello, world!
操作符的优先级和关联性
Scala 基于操作符格式里方法的第一个字符决定优先级(除非是赋值操作符)。比方说,如果方法名开始于*,那么就比开始于+的方法有更高的优先级。因此a +++ b *** c将被看作是a +++ (b *** c),因为***方法比+++方法有更高的优先级。
操作符优先级
(所有其他的特殊字符)
* / %
+ -
:
= !
< >
&
^
|
(所有字母)
同一行的字符具有同样的优先级。字符的位置越高,以这个字符开始的方法具有的优先级就越高:
scala> 2 << 2 + 2
res6: Int = 32
<< 方法开始于字符 < ,在表格5.3里的位置比 + 要低。因此 << 比 + 的优先级低,表达式也要在先调用了 + 方法之后再调用 << 方法,表现为: 2 << (2 + 2) 。
有关于以等号结束的赋值操作符:assignment operator。如果操作符以等号字符(=)结束,且操作符并非比较操作符 <= , >= , == ,或 = ,那么这个操作符的优先级与赋值符(=)相同。也就是说,它比任何其他操作符的优先级都低:
x *= y + 1
与下面的相同:
x *= (y + 1)
因为 *= 被当作赋值操作符,它的优先级低于 + 。
当同样优先级的多个操作符肩并肩地出现在表达式里,操作符的关联性:associativity决定了操作符分组的方式。 Scala 里操作符的关联性取决于它的最后一个字符。,任何以‘:’字符结尾的方法由它的右手侧操作数调用,并传入左操作数。以其他字符结尾的方法都是被左操作数调用,并传入右操作数。因此 a * b 变成 a.*(b) ,但是 a:::b 变成 b.:::(a) 。然而不论操作符具有什么样的关联性,它的操作数总是从左到右评估的。因此如果 b 是一个表达式而不仅仅是一个不可变值的指针的话,那么更精确的意义上说, a:::b 将会当作是:
{ val x = a; b.:::(x) }
这个代码块中, a 仍然在 b 之前被评估,然后评估结果被当作操作数传给 b 的 ::: 方法。
这种关联性规则在同时使用多个具有同优先级的操作符时也会起作用。如果方法结束于 : ,它们就被自右向左分组;反过来,就是自左向右分组。例如, a ::: b ::: c 会被当作 a ::: (b ::: c) 。而 a * b * c 被当作 (a * b) * c 。
Scala 编程(三)基本类型和操作的更多相关文章
- Scala编程--基本类型和操作
如果你熟悉Java,你会很开心地发现Java基本类型和操作符在Scala里有同样的意思.然而即使你是一位资深Java开发者,这里也仍然有一些有趣的差别使得本章值得一读.因为本章提到的一些Scala的方 ...
- scala编程(五)——基本类型和操作
文本 文本是直接在代码里写常量值的一种方式以.在Scala中并不显式的使用Int或float,而是以文本的方式写成 val 变量. 如果整数文本结束于 L 或者 l,就是 Long 类型,否则就是 I ...
- scala 基本类型和操作
Scala基本类型 Scala中的基本数据类型如下图: (来源:Programming in scala) 从上表中可以看出,Scala的基本数据类型与Java中的基本数据类型是一一对应的,不同的是 ...
- Scala学习笔记(八):基本类型和操作
基本类型: 整数类型=>数类型 字面量:字面量就是直接写在代码里的常量值 字面量是指由字母.数字等构成的字符串或者数值,它只能作为右值出现,所谓右值是指等号右边的值,如:int a=123这里的 ...
- Scala学习(三)----数组相关操作
数组相关操作 摘要: 本篇主要学习如何在Scala中操作数组.Java和C++程序员通常会选用数组或近似的结构(比如数组列表或向量)来收集一组元素.在Scala中,我们的选择更多,不过现在我们先假定不 ...
- Scala学习三——数组相关操作
一.若长度固定则使用Array,若长度可能有变化则使用ArrayBuffer 固定长度数组: 如val nums=new Array[Int](10) //10个整型数组,所有元素初始化为0; val ...
- Linux网络编程三、 IO操作
当从一个文件描述符进行读写操作时,accept.read.write这些函数会阻塞I/O.在这种会阻塞I/O的操作好处是不会占用cpu宝贵的时间片,但是如果需要对多个描述符操作时,阻塞会使同一时刻只能 ...
- redis基本类型和操作
基本类型:string hash list set sorted set 添加String 类型(最基本的key,value形式) set str1 s1 获取value get str1 添加has ...
- (升级版)Spark从入门到精通(Scala编程、案例实战、高级特性、Spark内核源码剖析、Hadoop高端)
本课程主要讲解目前大数据领域最热门.最火爆.最有前景的技术——Spark.在本课程中,会从浅入深,基于大量案例实战,深度剖析和讲解Spark,并且会包含完全从企业真实复杂业务需求中抽取出的案例实战.课 ...
随机推荐
- 一行代码实现iOS序列化与反序列化
一.变量声明 为便于下文讨论,提前创建父类Biology以及子类Person: Biology: @interface Biology : NSObject { NSInteger *_hairCou ...
- Android蓝牙操作笔记(转)
蓝牙是一种支持设备短距离传输数据的无线技术.android在2.0以后提供了这方面的支持. 从查找蓝牙设备到能够相互通信要经过几个基本步骤(本机做为服务器): 1.设置权限 在manifest中配置 ...
- java.lang.ClassCastException: android.view.ViewGroup$LayoutParams cannot be cast to android.widget.L(转)
09-09 10:19:59.979: E/AndroidRuntime(2767): FATAL EXCEPTION: main09-09 10:19:59.979: E/AndroidRuntim ...
- Android(java)学习笔记239:多媒体之撕衣服的案例
1.撕衣服的案例逻辑: 是两者图片重叠在一起,上面我们看到的是美女穿衣服的图片,下面重叠(看不到的)是美女没有穿衣服的图片.当我们用手滑动画面,上面美女穿衣服的图片就会变成透明,这样的话下 ...
- Ubuntu下全命令行安装Android SDK
为了在AWS云服务器上实现自动化打包Android APP的APK包,我需要远程命令行环境下安装Android SDK,当然还要用代理或者科学上网,这里简单整理一下过程: 首先,由于墙的原因,Andr ...
- Android 连接 SQL Server (jtds方式)——上
本文将介绍开发Android程序,连接SQL Server,通过第三方包jtds的方式. 如果你有同样的需求,请跟着做一遍,博主将以最详细的方式,进行介绍. 首先说明,Java.Android连接SQ ...
- RxJava 教程-1 简介 原理 线程控制 变换
简介 RxJava 是什么? RxJava 在 GitHub 主页上的自我介绍是 RxJava is a Java VM implementation of ReactiveX: a library ...
- 基于laravel4.2的相关架构设计
项目组不久前引进了laravel框架,本人参与了laravel的调研和项目架构设计.个人认为项目架构中基于laravel的有些设计还是比较实用和有借鉴性的,现将一些设计分享给大家,希望能和大家共同学习 ...
- java中的IO二
java中流分为节点流和处理流,IO一中的案例都是节点流 一.处理流的使用实例 二.装饰者模式 以上BufferReader的用法就是装饰者模式 Decorator就是动态地给对象增添行为 如果要实现 ...
- 开源的Android开发框架-------PowerFramework使用心得(一)总体介绍
PowerFramework是一款几乎囊括了所有Android基础功能的框架应用,这个框架目前是开源的,开发者可以在这个框架的基础上进行二次开发.结合开发者自己的UI设计,可以很快就能开发出具备基础应 ...