Scala基本类型
Scala中的基本数据类型如下图:
(来源:Programming in scala)
从上表中可以看出,Scala的基本数据类型与Java中的基本数据类型是一一对应的,不同的是Scala的基本数据类型头字母必须大写,本节以Int、Long、String、Char、Double及Float类型为例介绍Scala的基本类型定义
整数类型变量定义:
-
//16进制定义法
-
scala> val x=0x29
-
x: Int = 41
- 1
-
//十进制定义法
-
scala> val x=41
-
x: Int = 41
-
//八进制定义法
-
scala> 051
-
res0: Int = 41
浮点类型变量定义:
-
//Double类型定义,直接输入浮点数,编译器会将其自动推断为Double类型
-
scala> val doubleNumber=3.141529
-
doubleNumber: Double = 3.141529
-
//要定义Float类型浮点数,需要在浮点数后面加F或f
-
scala> val floatNumber=3.141529F
-
floatNumber: Float = 3.141529
-
-
scala> val floatNumber=3.141529f
-
floatNumber: Float = 3.141529
- 1
浮点类型的变量还可以采用指数表示法,如
-
//浮点数指数表示法,e也可以是大写E,0.314529e1与0.314529*10等同
-
scala> val floatNumber=0.314529e1
-
floatNumber: Double = 3.14529
- 1
字符变量定义:
-
//字符定义,用''将字符包裹
-
scala> var charLiteral='A'
-
charLiteral: Char = A
- 1
常用特殊字符包括
\n 换行符,其Unicode编码为 (\u000A)
\b 回退符,其Unicode编码为 (\u0008)
\t tab制表符 ,其Unicode编码(\u0009)
\” 双引号,其Unicode编码为 (\u0022)
\’ 单引号,其Unicode编码为 (\u0027)
\ 反斜杆,其Unicode编码为(\u005C)
字符串变量定义:
-
//字符串变量用""包裹
-
scala> val helloWorld="Hello World"
-
helloWorld: String = Hello World
-
-
//要定义"Hello World",可以加入转义符\
-
scala> val helloWorldDoubleQuote="\"Hello World\""
-
helloWorldDoubleQuote: String = "Hello World"
-
-
//如果希望能够原样输出字符串中的内容,则用三个引号"""将字符串包裹起来,如
-
scala> println( """ hello cruel world, \n \\\\ \b \\, I am " experienced" programmer""")
-
hello cruel world, \n \\\\ \b \\, I am " experienced" programmer
布尔类型定义:
-
scala> var x=true
-
x: Boolean = true
Scala基本类型操作
在Scala中一切操作皆方法,这意味着Scala中的一切皆为对象
算术操作:
-
//整数求和,编译器会将其转换为(1).+(2)执行
-
scala> var sumVlaue=1+2
-
sumVlaue: Int = 3
-
-
//前一语句等同于下列语句
-
scala> var sumVlaue=(1).+(2)
-
sumVlaue: Int = 3
-
-
//操作符重载,编译器会将其转换为(1).+(2L)执行
-
scala> val longSum = 1 + 2L
-
longSum: Long = 3
-
-
//减法
-
scala> 1-3
-
res5: Int = -2
-
-
//除法
-
scala> 1/3
-
res6: Int = 0
-
-
//取模
-
scala> 1%3
-
res7: Int = 1
-
-
//乘法
-
scala> 1L*3L
-
res8: Long = 3
-
-
//scala中可以用+ -符号来表示正负数,例如-3 +3,并且可以加入到运算符当中
-
scala> var y=1+ -3
-
y: Int = -2
- 7
关系运算:
-
//>运算符
-
scala> 3 > -3
-
res12: Boolean = true
-
//<运算符
-
scala> 3 < -3
-
res13: Boolean = false
-
//<=运算符
-
scala> 3 <= -3
-
res14: Boolean = false
-
//<=运算符
-
scala> 3 <=3
-
res15: Boolean = true
-
//<=运算符
-
scala> !( 3<= -3)
-
res16: Boolean = true
- 1
逻辑运算:
-
//逻辑与:&&
-
scala> val bool=true
-
bool: Boolean = true
-
-
scala> bool && bool
-
res17: Boolean = true
-
//逻辑或:||
-
scala> bool || bool
-
res18: Boolean = true
-
-
-
scala> bool || !bool
-
res20: Boolean = true
- 3
位运算:
-
// 00000001
-
// 00000010
-
// 00000000
-
scala> 1 & 2
-
res24: Int = 0
-
-
// 00000001
-
// 00000010
-
// 00000011
-
scala> 1 | 2
-
res24: Int = 3
-
-
// 00000001
-
// 00000011
-
// 00000010
-
scala> 1 ^ 3
-
res24: Int =2
-
-
//00000001
-
//11111110
-
scala> ~ 1
-
res24: Int =-2
-
-
//左移位(shift left)
-
//00000110
-
//00001100
-
scala> 6 << 1
-
res29: Int = 12
-
-
//右移位(shift left)
-
//00000110
-
//00000011
-
scala> 6 >> 1
-
res28: Int = 3
-
-
//无符号右移(shift left)
-
//11111111111111111111111111111111
-
//00000000000000000000000000000001
-
scala> -1 >>> 31
-
res32: Int = 1
- 1
- 2
对象比较:
-
scala> 1==1
-
res34: Boolean = true
-
-
scala> 1==1.0
-
res35: Boolean = true
-
-
scala> val x= "Hello"
-
x: String = Hello
-
-
scala> val y= "Hello"
-
y: String = Hello
-
-
//Scala中的对象比较不同于Java中的对象比较
-
//Scala基于内容比较,而java中比较的是引用,进行内容比较时须定义比较方法
-
scala> x==y
-
res36: Boolean = true
- 1
运算符的优先级:
运算符优先级如下图所示,* / %优先级最高,依次类推
图片来源:Programming in Scala
Scala程序控制结构
if 的使用:
val x= if("hello"=="hell") 1 else 0
- 1
while 的使用:
-
def gcdLoop(x: Long, y: Long): Long = {
-
var a = x
-
var b = y
-
while (a != 0) {
-
val temp = a
-
a = b % a
-
b = temp
-
}
-
b
-
}
- 2
do while的使用
-
var line = ""
-
do {
-
line = readLine()
-
println("Read: "+ line)
-
} while (line != "")
- 1
注意:与if不同的是,while与do while不能用作表达式,也即其返回值为Unit,在某些函数式编程语言中,删除了while与do while程序控制结构,但scala仍然保留了while与do while,可见Scala并不是纯函数式编程语言(另外一个重要原因是,scala函数定义时仍然可以用var指定参数)。
-
//利用 if替代while控制结构
-
//这些做可以减少var变量的使用,程序结构也更简单,表达能力更强
-
def gcd(x: Long, y: Long): Long =
-
if (y == 0) x else gcd(y, x % y)
- 3
-
var line = ""
-
while ((line = readLine()) != "") // 在Scala中不能这么用,因为Scala中的赋值操作返回的值是Unit,而""是String类型,不能进行比较,这是函数式编程语言特有的特点
-
println("Read: "+ line)
- 2
for循环的使用
-
scala> val filesHere = ( new java.io.File(".")).listFiles
-
//集合操作方式
-
scala> for (file <- filesHere)
-
| println(file)
-
-
//间接调用方式(不常用)
-
for (i <- 0 to filesHere.length - 1)
-
println(filesHere(i))
- 1
//程序中的<-被称生成器(generator),在执行过程中,集合filesHere中(Array[File])的元素将依次赋给file,file类型为File,打印时调用其toString方法将文件名称打印出来。
-
scala> val filesHere = ( new java.io.File(".")).listFiles
-
filesHere: Array [java.io.File] = Array(.\.android, .\.idea-build, .\.IdeaIC14, .
-
\.ivy2, .\.m2, .\.sbt, .\.scala_history, .\AppData, .\Application Data, .\Contac
-
ts, . \Cookies, .\Desktop, .\Documents, .\Downloads, .\Favorites, .\hello, .\Link
-
s, . \Local Settings, .\Music, .\My Documents, .\NetHood, .\NTUSER.DAT, .\ntuser.
-
dat.LOG1, . \ntuser.dat.LOG2, .\NTUSER.DAT{016888bd-6c6f-11de-8d1d-001e0bcde3ec}.
-
TM.blf, . \NTUSER.DAT{016888bd-6c6f-11de-8d1d-001e0bcde3ec}.TMContainer0000000000
-
0000000001.regtrans-ms, .\NTUSER.DAT{016888bd-6c6f-11de-8d1d-001e0bcde3ec}.TMCon
-
tainer00000000000000000002.regtrans-ms, . \ntuser.ini, .\Pictures, .\PrintHood, .
-
\Recent, .\Roaming, .\Saved Games, .\Searches, .\SendTo, .\target, .\Templates,
-
. \Videos, .\「开始」菜单)
-
-
scala> for (file <- filesHere)
-
| println(file)
-
. \.android
-
. \.idea-build
-
. \.IdeaIC14
-
. \.ivy2
-
. \.m2
-
. \.sbt
-
. \.scala_history
-
. \AppData
-
. \Application Data
-
. \Contacts
-
. \Cookies
-
. \Desktop
-
. \Documents
-
. \Downloads
-
. \Favorites
-
. \hello
-
. \Links
-
. \Local Settings
-
. \Music
-
. \My Documents
-
. \NetHood
-
. \NTUSER.DAT
-
. \ntuser.dat.LOG1
-
. \ntuser.dat.LOG2
-
. \NTUSER.DAT{016888bd-6c6f-11de-8d1d-001e0bcde3ec}.TM.blf
-
. \NTUSER.DAT{016888bd-6c6f-11de-8d1d-001e0bcde3ec}.TMContainer000000000000000000
-
01.regtrans-ms
-
. \NTUSER.DAT{016888bd-6c6f-11de-8d1d-001e0bcde3ec}.TMContainer000000000000000000
-
02.regtrans-ms
-
. \ntuser.ini
-
. \Pictures
-
. \PrintHood
-
. \Recent
-
. \Roaming
-
. \Saved Games
-
. \Searches
-
. \SendTo
-
. \target
-
. \Templates
-
. \Videos
-
. \「开始」菜单
- 1
<-生成器对其它类型的集合也适用,
-
scala> 1 to 5
-
res39: scala.collection.immutable. Range.Inclusive = Range(1, 2, 3, 4, 5)
-
-
scala> for(i <- res39) println("Iteration"+i)
-
Iteration1
-
Iteration2
-
Iteration3
-
Iteration4
-
Iteration5
-
-
也可直接简写成
-
scala> for(i <- 1 to 5) println("Iteration"+i)
-
Iteration1
-
Iteration2
-
Iteration3
-
Iteration4
-
Iteration5
-
-
//如果不需要5出现,则用
-
scala> for(i <- 1 until 5) println("Iteration"+i)
-
Iteration1
-
Iteration2
-
Iteration3
-
Iteration4
- 4
在for循环结构中还可以加入if进行过滤操作
-
val filesHere = ( new java.io.File(".")).listFiles
-
for (file <- filesHere if file.getName.endsWith(".scala"))
-
println(file)
-
//还可以加入多个过滤条件,用;隔开
-
for (
-
file <- filesHere
-
if file.isFile;
-
if file.getName.endsWith(".scala")
-
) println(file)
//多重循环的实现:
-
def fileLines( file: java.io.File) =
-
scala.io.Source.fromFile( file).getLines.toList
-
def grep(pattern: String) =
-
for (
-
file <- filesHere
-
if file.getName.endsWith(".scala");
-
line <- fileLines( file)
-
if line.trim.matches(pattern)
-
) println( file +": "+ line.trim)
-
grep(".*gcd.*")
-
-
//前一个for相当于下列语句
-
def grep(pattern: String) =
-
for (
-
file <- filesHere
-
if file.getName.endsWith(".scala")
-
)
-
for(
-
line <- fileLines( file)
-
if line.trim.matches(pattern)
-
)
-
println( file +": "+ line.trim)
-
grep(".*gcd.*")
生成返回结果
-
//每次循环将结果保留,当整个循环执行完毕,所有保留的值将会生成一个集合并返回
-
scala> def scalaFiles =
-
| for {
-
| file <- filesHere
-
| if file.getName.endsWith(".scala")
-
| } yield file
-
scalaFiles: Array[java.io.File]
-
-
//Array[File]到Array[Int]的转换
-
scala> val forLineLengths =
-
| for {
-
| file <- filesHere
-
| if file.getName.endsWith(".scala")
-
| line <- fileLines( file)
-
| trimmed = line. trim
-
| if trimmed.matches(".*for.*")
-
| } yield trimmed.length
-
forLineLengths: Array[Int] = Array()