文章目录
scala变量定义|数据类型|运算符|流程控制|Option类
- scala中,所有东西都是某个类型下的实例,方法,函数也是实例,方法或函数可以当做其他方法和函数的参数;+ - * / 实际是方法;(python类同:类、方法、函数也可以当做参数传递)
- scala中所有的方法都有返回值,或是Unit
- idea中按住‘ctrl’键点击方法,可以查看方法源码;
- {}是有返回值的,返回值是{}中的最后一个代码的返回值,如果最后一句代码是一变量,则返回这一变量;
变量定义
-
使用的是关键字定义,定义变量的时候:变量名称必须给出,变量的值可以延迟初始化;;
- val:声明常量;var:声明变量
- 使用lazy关键字延迟初始化,比如读取文件返回,使用lazy定义,减少即时内存占有;
val num:Int = 10 val num = 10 // 类型推断 val num:Int // 变量值延迟初始化 val db = 1.1 // 推断出来是Double类型 val db:Float = 1.1 // 报错,类型不匹配,可以指定Float类型 val db:Float = 1.1f val num = 3 / 2 // 返回的是1(推断两个int相除返回int),而不是1.5,跟python有区别; val num:Double = 3 / 2 // 返回是1.0,而并非1.5 val num = 3f / 2 // 返回3float,2int的共同的类float:1.5 var num2:Any = 100 // 定义变量 num2 = 1000 // 变量值可以修改为值所在类范畴的其他值 num2 = "Any类型也可以赋值string" // 变量值使用lazy关键字定义,只有在调用时才会运行; lazy val num2 = { // 这里是一块代码 b = 2; // 代码的结束符“;”一般不使用 return b // 代码块最后一行是返回值,return为返回关键字,一般不使用 }
数据类型
数据类型基本介绍
-
Any是scala中所有类的父类,其他所有scala中的类型是Any的子类;
-
Nothing是scala中所有类型的子类,除了Nothing以外,其他所有类型都是Nothing的父类
-
Any只有两个直接子类:AnyVal(值类型)、AnyRef(引用类型)
-
Any包含两种类型(java中的八大基本类型,Uint)
- Char、Byte、Long、Short、Float、Double、Boolean
- Unit
-
Unit是一个单例对象:只有一个对象:()
-
val unit:Unit = ()
-
-
AnyRef是scala中所有引用类型的父类;
- 自定义和预定义的scala类型、集合类型,String;
-
Null是所有引用类型的子类,Nothing是Null的子类;
数据类型图表
数据类型 | 介绍 |
---|---|
Byte | 8位有符号补码整数。数值区间为 -128 到 127 |
Short | 16位有符号补码整数。数值区间为 -32768 到 32767 |
Int | 32位有符号补码整数。数值区间为 -2147483648 到 2147483647 |
Long | 64位有符号补码整数。数值区间为 -9223372036854775808 到 9223372036854775807 |
Float | 32 位, IEEE 754 标准的单精度浮点数 |
Double | 64 位 IEEE 754 标准的双精度浮点数 |
Char | 16位无符号Unicode字符, 区间值为 U+0000 到 U+FFFF |
String | 字符序列 |
Boolean | true或false |
Unit | 表示无值,和其他语言中void等同。用作不返回任何结果的方法的结果类型。Unit只有一个实例值,写成()。 |
Null | null 或空引用 |
Nothing | Nothing类型在Scala的类层级的最底端;它是任何其他类型的子类型。 |
Any | Any是所有其他类的超类 |
AnyRef | AnyRef类是Scala里所有引用类(reference class)的基类 |
数据结构图
- Nothing和Null类见上方介绍,结构图里不再做勾画;
scala定义的“空”
关于scala定义"空"这个概念有五种表示方法:
- Nothing 表示所有类型的子类,除此之外没有意义。是为了将来的泛型的语法准备
- Null 是对于java中的null问题的一个封装。
- None 表示存在与否的不存在
- Nil 表示空列表 List list = null; val list = Nil
- Unit 表示方法的空返回 java中如果一个方法没有返回值,就指定为void
运算符
算数运算符
+,-,*,/,%(取余数)
5 + 3
5.+(3)
// 以上两者是等价的,a 方法 b 与 a.方法(b)
5 % 3 // 2
5 / 3 // 推断两个int类型相除,返回的是1
3.0 / 2 // 返回是1.5,Double类型
scala中任何方法都可以是操作符
val str = "Hello World"
str.toLowerCase()
str.toLowerCase // 方法调用的空括号可以省略
str toLowerCase // 方法可以当操作符使用
关系运算符操作
>,<,>=,<=,!=,==,!:其中 ! 为取反操作,比如:
! true // false
5 != 4 // true
逻辑运算符
逻辑与“&&”,逻辑或“||”
true && false // false
true || false // true
位运算符
&(与):有一个为0,结果为0;
|(或):有一个1,结果为1;
^(异或):相同为0,不同为1;
<<(左移):左移n位,乘以2的n次方
>>(右移):右移n位,除以2的n次方
val a = 2 // 二进制:10
val b = 3 // 二进制:11
a & b // 返回10:十进制2
a | b // 返回11:十进制3
a ^ b // 返回1:十进制1
比较符
ne,eq:仅仅比较引用(内存一致),ne 是not eq简称;
equals:比较值
object Test {
def main(args: Array[String]): Unit = {
val obj1 = A
val obj2 = A
println(obj1 eq obj2)
}
}
object A
流程控制
if判断
- if条件判断是有返回值的,由多个分支组成,每个分支都有{},{}是有返回值的;
val num = if (3>2) {3} else {2} // 返回3
val num = if (3>2) 3 else 2 // 返回3,大括号里只有一个变量可以不写大括号;
val num = if (3>2) 3 else 'str' // 返回的是Int:3和String:str的父类,Any类型;
val num = if (3>2) 3 // 返回是AnyVal类型,Int和Unit的父类
// if else if else 语法
val num = if (3>2) {
">"
} else if(3==2){
"="
}else{
"<"
}
while的循环
// 1+2+3+...+100
object WhileTest {
def main(args: Array[String]): Unit = {
var num1 = 100
var num2 = 0
while(num1>0){
num2 += num1
num1 -= 1
}
println(num2) // 5500
}
}
for循环语句
1 to 10 // 从1到10
1 to(10) // 也可以使用to方法
10 to 1 bye -2 //10到1,步长为-2
Range(1,10,2) // 第三个参数是步长,左闭右开,右边10不包含,步长不能为0
1 until 10 //从1到9,遇0跳出循环
1.until(9,2) //从1到9,间隔为2:1,3,5,7
for(num <- 1 to (10,2)) println(num)
// 使用yield返回元素乘以2的数组;
val array = Array(1,2,3,4,5,6,7)
val array2 = for(e <- array) yield e * 2
//Long类型,使用l关键字
1L to 10L by 2
// BigInt 类型
BigInt(1) to BigInt(10) by 2
val courses = Array("语文","数学","英语")
// 循环数组每个元素输出右边函数结果
courses.foreach(course => println(course))
//while 循环,满足条件执行循环语句
var num = 10
while(num>1)(println(num);num = num - 1}
for(num <- 1 to 10) println(num) // 打印1到10
for(num <- 1 to (10,2)) println(num) // 从1打印到10,间隔为2
// 添加守卫条件
for(num <- 1 to 10 if num % 2 == 1) println(num) // 1,3,5,7,9
var array = Array(1,2,3,4,5)
// until到某个数结束,不包含这个数;数组可以使用索引访问;
for (index <- 0 until array.length) println(array(index))
// until间隔为2,跟to的方法是一样的;
for (index <- 0 until (array.length,2)) println(array(index))
- 双层for循环
// 打印乘法口诀表
for(a <- 1 to 9){for(b <- 1 to a){print(a + "*" + b + "=" + a*b + "\t")};println()}
// 使用双层循环,"${变量名}"可以自动查找变量
for(a <- 1 to 9;b <- 1 to a) print(s"${a} * ${b} = ${a*b}${if(a==b) "\n" else "\t"}")
模式匹配
匹配值
val value = 0
value match {
case 0 => "零"
case 1 => "壹"
case _ => "非零非壹"
}
// 模式匹配中,也可以使用变量
val value = 0
val valueMatch = value match {
case 0 => "0"
case 1 => "1"
case 2 => "2"
case other => s"其他值:${other}"
}
使用守卫进行匹配
val value = 150
value match {
case i if i <= 300 => "小R"
case i if i <= 100 => "中R"
case _ => "大R"
}
匹配类型
def instance(value:Any):Any = {
value match {
case i:Int if i < 0 => s"${i} 是一个小于0的整数"
case i:Int if i >= 0 => s"${i} 是一个大等于0的整数"
case d:Double if d < 0.0 => s"${d} 是一个小于0的Double类型数值"
case d:Double if d >= 0.0 => s"${d} 是一个大等于0的Double类型"
case str:String => s"${str} 是一个字符串"
}
}
匹配类成员
// 定义一个样本类
样本类可以方便存储和匹配类的内容,无须new关键字就可以创建他们;
case class Calculator(name:String,age:Int)
// 匹配用户的体重
def weightMatch(cal:Calculator) = {
case Calculator("张三",18) => 110
case Calculator("张三",23) => 145
case Calculator("李四",10) => 80
case _ => "其他人"
}
最后其他部分,也可以使用case Calculator(__, _) =>“其他人”
异常捕捉
在scala中异常使用try-catch-finally语法中通过模式匹配使用;同时try也是面向表达式的,有返回;
try {
remoteCalculatorService.add(1, 2)
} catch {
case e: ServerIsDownException => log.error(e, "the remote calculator service is unavailable. should have kept your trusty HP.")
} finally {
remoteCalculatorService.close()
}
Option类型
- scala中,使用Option情形比较多,会经常使用Option[T]类型,其中的T可以是String或者Int或者其他各种数据类型;
- Option[T]实际是一个容器,可以看做是一个集合,不过这个集合要么返回一个元素(被包含在Some中返回),要么就不存在元素(返回None),None调用println方法打印,屏幕上什么都不显示;
- 可以使用map、foreach、filter等集合方法;
- Option类型提供了getOrelse方法,这个方法在Option是Some的实例时返回对应的值,在None的实例时返回传入的参数。类似于excel中iferror中返回,如果报错返回传入参数,否则范湖对应结果值;
val map = Map("name" -> "zhangsan","age" -> 18)
val weightGet = map.get("weight")
// Option[String] = None 返回是Option类型
weightGet.getOrElse("没有weight键值对")
map.get("name")
// Option[String] = Some(zhangsan)
占位符语法
- 为了放函数字面更加简洁,可以使用下划线作为一个或多个参数的占位符,只要每个参数在函数字面量内仅出现一次;
val intArray = Array(1,2,3,43,5)
intArray.filter(num => num > 3)
intArray.filter(_ > 3) // 使用占位符语法与上面传入匿名函数是等价的;
val func = (_:Int) > 3
val add = _ + _ // 变量类型无法自动推断,会报错
val add = (_:Int) + (_:Int) // 可以指定类型
_ + _ 扩展成带两个参数的字面量,每个参数在函数字面量最多出现一次时才能使用这种呢格式;多个下划线指代多个参数,不是单个参数重复使用;第一个下划线使用第一个参数,第二个下划线使用第二个参数,第三个…以此类推;