一些基本类型

值类型

范围

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 编程(三)基本类型和操作的更多相关文章

  1. Scala编程--基本类型和操作

    如果你熟悉Java,你会很开心地发现Java基本类型和操作符在Scala里有同样的意思.然而即使你是一位资深Java开发者,这里也仍然有一些有趣的差别使得本章值得一读.因为本章提到的一些Scala的方 ...

  2. scala编程(五)——基本类型和操作

    文本 文本是直接在代码里写常量值的一种方式以.在Scala中并不显式的使用Int或float,而是以文本的方式写成 val 变量. 如果整数文本结束于 L 或者 l,就是 Long 类型,否则就是 I ...

  3. scala 基本类型和操作

    Scala基本类型 Scala中的基本数据类型如下图:  (来源:Programming in scala) 从上表中可以看出,Scala的基本数据类型与Java中的基本数据类型是一一对应的,不同的是 ...

  4. Scala学习笔记(八):基本类型和操作

    基本类型: 整数类型=>数类型 字面量:字面量就是直接写在代码里的常量值 字面量是指由字母.数字等构成的字符串或者数值,它只能作为右值出现,所谓右值是指等号右边的值,如:int a=123这里的 ...

  5. Scala学习(三)----数组相关操作

    数组相关操作 摘要: 本篇主要学习如何在Scala中操作数组.Java和C++程序员通常会选用数组或近似的结构(比如数组列表或向量)来收集一组元素.在Scala中,我们的选择更多,不过现在我们先假定不 ...

  6. Scala学习三——数组相关操作

    一.若长度固定则使用Array,若长度可能有变化则使用ArrayBuffer 固定长度数组: 如val nums=new Array[Int](10) //10个整型数组,所有元素初始化为0; val ...

  7. Linux网络编程三、 IO操作

    当从一个文件描述符进行读写操作时,accept.read.write这些函数会阻塞I/O.在这种会阻塞I/O的操作好处是不会占用cpu宝贵的时间片,但是如果需要对多个描述符操作时,阻塞会使同一时刻只能 ...

  8. redis基本类型和操作

    基本类型:string hash list set sorted set 添加String 类型(最基本的key,value形式) set str1 s1 获取value get str1 添加has ...

  9. (升级版)Spark从入门到精通(Scala编程、案例实战、高级特性、Spark内核源码剖析、Hadoop高端)

    本课程主要讲解目前大数据领域最热门.最火爆.最有前景的技术——Spark.在本课程中,会从浅入深,基于大量案例实战,深度剖析和讲解Spark,并且会包含完全从企业真实复杂业务需求中抽取出的案例实战.课 ...

随机推荐

  1. C#解leetcode 106. Construct Binary Tree from Inorder and Postorder Traversal

    Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assume that ...

  2. C#word(2007)操作类--新建文档、添加页眉页脚、设置格式、添加文本和超链接、添加图片、表格处理、文档格式转化

    转:http://www.cnblogs.com/lantionzy/archive/2009/10/23/1588511.html 1.新建Word文档 #region 新建Word文档/// &l ...

  3. Android之ListView/GridView 优化

    一.效率最低的getView实现 我们知道,ListView和GridView的显示都是通过Adapter的getView实现的. ListView/GridView数据量较小时,我们的处理方式一般是 ...

  4. struts.xml中的intercepter

    1. http://weizhilizhiwei.iteye.com/blog/1005210 Struts2 的核心——拦截器[Interceptor] 2. http://blog.csdn.ne ...

  5. Swift - 14 - 字符串的基础操作

    //: Playground - noun: a place where people can play import UIKit // 拼接 var str = "Hello, playg ...

  6. Hive学习之二 《Hive的安装之自定义mysql数据库》

    由于MySQL便于管理,在学习过程中,我选择MySQL. 一,配置元数据库. 1.安装MySQL,采用yum方式. ①yum  install  mysql-server,安装mysql服务端,安装服 ...

  7. svn更新

    下载配置文件 pwd cd /home/www/xxxx/protected/config/ get main.php 上传配置文件 put main.php svn更新 svn co svn://s ...

  8. WebAPI接口测试之matthewcv.WebApiTestClient

    WebAPI接口测试之matthewcv.WebApiTestClient matthewcv.WebApiTestClient 1.安装matthewcv.WebApiTestClient包 打开v ...

  9. angularJS中如何写控制器

    angularJS中的控制器是一个函数,用来向视图作用域中添加额外的功能,我们用它来给作用域对象设置初始状态,并添加自定义行为 当我们在页面上创建一个新的控制器时,angularJS会生成并传递一个新 ...

  10. Javascript模块化编程 require.js使用详解

    一.为什么用require.js,产生的背景 最早的时候,所有Javascript代码都写在一个文件里面,只要加载这一个文件就够了.后来,代码越来越多,一个文件不够了,必须分成多个文件,依次加载. & ...