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,并且会包含完全从企业真实复杂业务需求中抽取出的案例实战.课 ...
随机推荐
- AC自动机学习笔记
AC自动机 ----多个模板的字符串匹配 字典树Trie加上失配边构成 插入操作:ac.insert(p[i],i);构造失配函数:ac.getFail();计算文本串T中每个模板串的匹配数:ac.f ...
- __name__属性
#coding=utf-8#首先我们分别看一下这个模块在不同场景中的__name__的值print __name__ #其次我们看一下__name__属性的常用情况if __name__==" ...
- retrofit2 使用教程 及 Android 网络架构搭建 (原创)
squareup 推出 retrofit2 已经有一段时间了,现在的版本比较稳定,没有什么大坑了.网络上的教程要么太简单,只是个Demo:要么有些落时,要么复用性比较差,所以自己写个教程,供大家参考. ...
- Android 的 Relative Layout 常量
android:layout_above 将该控件的底部置于给定ID的控件之上 --Rule that aligns a child's bottom edge ...
- c# 使用递归 循环遍历导航树结构 并解析
1.数据书库结构 1 家用电器 0 一级菜单 2 手机.数码.京东通信 0 一级菜单 3 电脑.办公 0 一级菜单 4 家具.家居.厨房 0 一级菜单 5 男装.女装.童装.内衣 0 一级菜单 6 个 ...
- Linux和windows下清除svn保存的账号密码信息
linux是什么用户登录就是什么用户的home下,如root用户就是/root,如果xiangdong就是/home/xiangdong 用Svn时会有一种需求是需要换个帐号测试一下什么的,但往往有缓 ...
- cas sso单点登录系列5_cas单点登录增加验证码功能完整步骤
转:http://blog.csdn.net/ae6623/article/details/8919718 本篇教程cas-server端下载地址:解压后,直接放到tomcat的webapp目录下就能 ...
- Python自动化运维之20、HTML
一.HTML相关概念 HTML是英文Hyper Text Mark-up Language(超文本标记语言)的缩写,他是一种制作万维网页面标准语言(标记).相当于定义统一的一套规则,大家都来遵守他,这 ...
- IE6不完全支持!important
!important !important是CSS1中定义的语法,作用是提高指定样式规则的应用优先权.语法格式如:.demo{color:red !important;} IE6支持重定义的!impo ...
- UI基础 - UITabBarController
self.window = [[UIWindow alloc] init]; self.window.frame = [UIScreen mainScreen].bounds; oneViewCont ...