scala 基本类型和操作

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

浮点类型的变量还可以采用指数表示法,如

//浮点数指数表示法,e也可以是大写E,0.314529e1与0.314529*10等同
 
scala> val floatNumber=0.314529e1
 
floatNumber: Double = 3.14529

字符变量定义:

//字符定义,用''将字符包裹
scala> var charLiteral='A'
 
charLiteral: Char = A

常用特殊字符包括 
换行符,其Unicode编码为 (u000A) 
 回退符,其Unicode编码为 (u0008) 
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, 
 \\  \, I am " experienced" programmer""")
 
hello cruel world, 
 \\  \, I am " experienced" programmer

布尔类型定义:

scala> var x=true
 
x: Boolean = true

Scala基本类型操作

在Scala中一切操作皆方法,这意味着Scala中的一切皆为对象。

任何方法都可以是操作符

Scala里的操作符不是特殊的语法:任何方法都可以是操作符。到底是方法还是操作符取决于你如何使用它。

例如:

如果写成s.indexOf('0’),indexOf就不是操作符。

如果写成s indexOf '0'那么indexOf就是操作符,因为你以操作符标注方式使用它。

Scala中的3类操作符:

  • 中缀(infix)操作符(标注):操作符位于对象和传递给方法的参数或若干参数之间。例如:“7 + 2”。
  • 前缀操(prefix)作符(标注):方法名被放在调用的对象之前。例如:- 7 里的“-”。只有+、-、!和~。
  • 后缀(subfix)操作符(标注):方法放在对象之后。例如:“7 toLong”里的“toLong”。

与中缀操作符--两个操作数,分别再操作符的左右两侧,前缀和后缀操作符都是一元(unary)的:它们仅有一个操作数。前缀方式中,操作数在操作符右边。

 

算术操作:

//整数求和,编译器会将其转换为(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

关系运算:

//>运算符
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

逻辑运算:

//逻辑与:&&
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

位运算:

// 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

对象比较:

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

运算符的优先级: 
运算符优先级如下图所示,* / %优先级最高,依次类推 

图片来源:Programming in Scala

Scala程序控制结构

if 的使用:

val x= if("hello"=="hell")  1 else 0

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
}

do while的使用

var line = ""
 
do {
 
line = readLine()
 
println("Read: "+ line)
 
} while (line != "")

注意:与if不同的是,while与do while不能用作表达式,也即其返回值为Unit,在某些函数式编程语言中,删除了while与do while程序控制结构,但scala仍然保留了while与do while,可见Scala并不是纯函数式编程语言(另外一个重要原因是,scala函数定义时仍然可以用var指定参数)

//利用if替代while控制结构
//这me做可以减少var变量的使用,程序结构也更简单,表达能力更强
def gcd(x: Long, y: Long): Long =
if (y == 0) x else gcd(y, x % y)
 
var line = ""
while ((line = readLine()) != "") // 错误,在Scala中不能这么用,因为Scala中的赋值操作返回的值是Unit,而""是String类型,不能进行比较,这是函数式编程语言特有的特点 
println("Read: "+ line)

//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))

//程序中的<-被称生成器(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, .
tuser.
 
dat.LOG1, .
tuser.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, .
tuser.ini, .Pictures, .PrintHood, .
 
Recent, .Roaming, .Saved Games, .Searches, .SendTo, .	arget, .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
 
.
tuser.dat.LOG1
 
.
tuser.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
 
.
tuser.ini
 
.Pictures
 
.PrintHood
 
.Recent
 
.Roaming
 
.Saved Games
 
.Searches
 
.SendTo
 
.	arget
 
.Templates
 
.Videos
 
.「开始」菜单

<-生成器对其它类型的集合也适用,

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

在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()

原文地址:https://www.cnblogs.com/duanxz/p/9461455.html