Scala基础
Scala基础知识
变量
var|val 变量名 [: 变量类型] = 变量值
val name: 类型 = 值 定义的变量不能修改,类似与java中final修饰的变量
var name: 类型 = 值 定义的变量可以修改
=注意=
- 声明变量时,类型可以省略(编译器自动推导,即类型推导)
- 类型确定后,就不能修改,说明Scala是强数据类型语言
- 在声明一个变量时,可以使用var或者val 修饰,var修饰的变量可以改变,val修饰的变量不可改变
object Hello {
def main(args: Array[String]): Unit = {
//类型推导
var num = 10
//类型确定后,就不能修改,说明Scala是强数据类型语言
// num = 2.3 //错误,因为scala已经推导出num就是Int类型
var age: Int = 30 //age是可以改变的
age = 50
val grade = 60
// grade = 80 //val修饰的变量不可以改变
}
}
scala设计者为什么设计var和val
(1) 在实际的应用场景中,我们更多的需求是获取/创建一个对象后,读取该对象的属性,我们很少去改变这个对象本身,这时我们可以使用val
(2) 因为val没有线程安全问题,因此效率更高,Scala设计者更加推荐我们使用val
(3) 如果对象需要改变,则使用var
(4) val修饰的变量在编译后,等同于加上final
(5) var修饰的对象引用可以改变,val修饰的则不可改变,但对象的状态(值)缺是可以改变的。
数据类型
Byte、Char、Short、Int、Long、Float、Double (无包装类型)和Boolean、Unit类型。scala中数据类型都是对象,因此每种数据类型都可以调用该对象的很多方法
Unit表示无值,和Java中void等同。用作不返回任何结果的方法的结果类型,但是在scala中表现形式为()
Any:所有变量的父类,类似于java中的Object
AnyVal:Byte、Char、Short、Int、Long、Float、Double、Boolean、Unit
AnyRef:除了上面的九种是Anyval,其他都是AnyRef类型
特殊类型
Unit:unit等价与java中的void,只有一个实例值()
Null:Null类只有一个实例对象,null,类似于java中null引用,null可以赋值给任意的引用
类型(AnyRef),但是不能赋值给值类型(AnyVal)
Nothing:Nothing类型在scala的类层级的最低端,它是任何其他类型的子类型。
当一个函数,我们确定没有正常的返回值,可以用Nothing来指定返回类型。
这样有一个好处,就是我们可以把返回的值(异常)赋给其他的函数或者变量(兼容性)
Scala数据类型系体系
=总结=
1) 在scala中有一个根类型Any,它是所有类的父类
2) scala中一切皆为对象,分为两大类 AnyVal(值类型),AnyRef(引用类型),它们都是Any子类
3) Null类型是scala的特别类型,它只有一个值null,它是bottom class,是所有AnyRef类型的子类
4) Nothing也是bottom class,它是所有类的子类,在开发中通常可以将Nothing类型的值返回给任意变量或者函数
//比如开发中,我们有一个方法,就会抛出异常,这时就可以返回Nothing
//即当我们Nothing做返回值,就是明确说明该方法没有任何正常返回值
def sayHello: Nothing = {
throw new Exception("抛出异常")
}
- 在scala中仍遵守,低精度的值,向高精度的值自动转换(implicit conversion) 隐式转换
var num = 1.2 //默认为double
var num2 = 1.7f
num = num2
//num2 = num //erro 修改为num2 =num.toFloat
懒值
Java中并没有为惰性提供原生支持
//在x被定义的时候即被取值
val x = scala.io.Source.fromFile("*/xxx/xx").mkString
//在y被首次使用时取值
lazy val y = scala.io.Source.fromFile("*/xxx/xx").mkString
//在每一次x被使用时取值
def z = scala.io.Source.fromFile("/xxx/xx/x").mkString
//懒值并不是没有额外开销,我们每次访问懒值,都会有一个方法被调用,而这个方法将会以线程安全的方式
//检查该值是否已被初始化
lazy不能修饰var变量
表达式
s"${表达式}" {这里面可以添加表达式,注意""的前面有一个s}
val name = "chenliqi"
println(s"${name }") //输出chenliqi
println(s"${4*4 }") //输出16
条件判断
Scala中没有三元运算符
/**
* if() {} else {},其中{}中最后一行代码是返回值
* if(){}else if(){} 可以不写最后的else,如果执行到最后的else,
* 编译器会帮我们返回一个Unit类型,这在java中会报错!
*/
val t = if (i>10) i else "xxxx" //在这里编译器会将t推导为Any类型
=注意=
- 如果大括号{} 内的逻辑代码只有一行,大括号可以省略,这点和java的规定是一样的
- Scala中任意表达式都是有返回值的,也就是意味着if else 表达式其实是有返回结果的,具体返回结果的值取决于满足条件的代码体的最后一行内容
- 在scala中没有switch,而是使用模式匹配来处理match - case
循环
for循环
scala中for循环这一常见的控制结构提供了非常多的特性,这些for循环的特性被称为for推导式或for表达式
//生成序列
0 to 5 Range(0, 1, 2, 3, 4, 5)
0 until 5 Range(0, 1, 2, 3, 4)
for(ele <- array){if(ele %2 == 0) println(ele)}
//用下标遍历
for(ele <- 0 until 4){println(array(ele))}
for(ele <- array; if ele % 2 == 0){println(ele)} for表达式中可以增加if。 类似于java中的continue
双重循环
for(i <- 1 to 3; j <- 1 to 3;if i!=j){println(10 * i + j +" ")}
while循环
和Java类似
var i = 0
while (i<10){
println("chen " + i)
i += 1
}
=注意=
- 循环条件是返回一个布尔值的表达式
- while循环是先判断再执行语句
- 与if语句不同,while语句本身没有值,即整个While语句的结果是Unit类型的()
- 因为while中没有返回值,所以当要用该语句来计算并返回结果时,就不可避免的使用变量,而变量需要声明再while循环的外部,那么就等同于循环的内部对外部的变量造成了影响,所以不推荐使用,而是推荐使用for循环
循环中断
在scala中并没有提供break和continue,但是util.control.Breajs,breakable提供了break
import scala.util.control.Breaks.breakable
import scala.util.control.Breaks
//类似于break
breakable{
for (ele <- 1 to 10) {
if (ele == 4) Breaks.break()
print(ele + " ")
}
}
//类似于continue 其实在for中添加if else也可实现continue效果
for (ele <- 1 to 10) {
breakable{
if (ele == 4) Breaks.break()
print(ele + " ")
}
}
/**
* breakable的源代码
* def breakable(op: => Unit) {
* try {
* op
* } catch {
* case ex: BreakControl =>
* if (ex ne breakException) throw ex
* }
* }
*/
yield
满足条件的返回,产生的新值放入集合中,将循环导出项链
//java中就需要list.add(ele)
val tt = for (ele <- 0 to 8 ; if ele %2 == 0) yield ele
println(tt)
运算符重载
1 + 2 = 1.+(2)
1 to 10 = 1.to (10)
异常
Scala中不再分编译异常和运行时异常
scala异常的工作机制和java一样,当我们抛出异常时
throw new IllegalArgumentException("xxxxxxxxxx")
scala中try catch 语法采用模式匹配
try{
xxxxxxxxxx
}catch {
//如果把范围小的写在后面,scala虽然不会报错,但是没有意义,
//且范围小的代码并不会得到执行
case ex:ArithmeticException => 做异常操作
case ex:IOException => 做异常处理
case ex:Exception => 做异常处理
}finally{
}
可以在代码中明确地抛出异常。Scala提供throws关键字来抛出异常。和java一样Scala提供了throws关键字来声明异常。可以使用方法定义声明异常。它向调用者函数提供了此方法可能引发此异常的信息。
scala的设计者并不支持“受检”异常,也就是对于声明的异常不是强制需要在程序中捕获,因为它们意识到彻底的编译器检查并不总是好的,也就是编程者觉得代码可能会出现异常就去try,编程者觉得没问题就不管了