scala 基础
scala基础
#scala
1.1 值和变量
使用var声名一个变量
- var修饰的变量,内容和引用都可以变
- 使用val声名一个常量或值
- val修饰的变量是不可变的,注意不可变的不是是内容,而是引用;
- 扩展一下什么是值类型,什么是引用类型,可以使用数据举例,引用不可变,变的是内容
/*
可变和不可变
可变和不可变,指的是变量本身存的内容,值类型变量存的是数据本身,而引用类型变量存的是数据的引用,
值类型和引用类型的区别?
存储方式:直接存储数据本身vs存储的是数据的引用,数据存放在数据堆中
内存分配:分配在栈中 vs 分配在堆中
效率:效率不高,不需要地址转换 vs 效率低,需要进行地址转换
内存回收:使用完后立即回收 vs 使用完后不立即回收,而是交给GC处理回收
*/
scala>val arr = array(1,2,3,4,5)
arr: Array[Int] = Array(1, 2, 3, 4, 5)
scala> arr = Array(1,2,3) <console>:8: error: reassignment to val arr = Array(1,2,3) scala> arr(0)=10 scala> arr res1: Array[Int] = Array(10, 2, 3, 4, 5)
Val修饰的变量,相当于java中final修饰的变量
lazy
只有val修饰的变量才能被lazy修饰;使用lazy定义变量后,只有在调用该变量的时候才会实例化这个变量的值,而且惰性变量只能是不可变变量
类似方法,先声明后调用
scala> val a = 10
a: Int = 10
scala> lazy val b=100
b: Int = <lazy>
scala> b
res0: Int = 100
scala> var c =10
c: Int = 10
scala> lazy var d = 100
<console>:1: error: lazy not allowed here. Only vals can be lazy
lazy var d = 100
^
scala> def e = 1000
e: Int
scala> e
res1: Int = 1000
1.2 常用类型
2.1 数值类型
Scala和java一样,有8种数值类型Byte,Char,Short,Int,Long,Float,Double和一个Boolean类型,
和java不同的是,scala没有基本类型和包装类型之分,这些类型都是类,有自己的属性和方法
相当于java的包装类
- toString()
- to (10)
2.2 scala 类型层级关系
Scala中所有值都有类型,包括数值和函数
[image:BE7FB4EA-E30A-4F02-9C45-4035D0BEE358-19742-0000F6D778E5A8D5/屏幕快照 2018-10-27 11.04.50.png]
Unit也是值类型 ,他只有一个实例对象()
Nothing 是所有类型的子类,他没有一个具体的实例对象,一个常见的应用如:抛出异常,程序exit,无限循环等
Nothing 是所有类型的子类,也是Null的子类。Nothing没有对象,但是可以用来定义类型。例如,如果一个方法抛出异常,则异常的返回值类型就是Nothing*(虽然不会返回)
def get(index:Int):Int = {
if(x<0) throw new Exception(...)
else.....
}
if 语句是表达式,有返回值,必然有返回值类型,如果 x<0 ,抛出异常,返回值的类型为nothing,Nothing也是Int的类型,所以,if表达式的返回值类型为Int ,get方法的返回值类型也为Int
Null是所有引用类型的子类,他只有一个实例对象null,主要用来和其他的jvm语言进行操作。
2.3 scala类型转化:
[image:07C1C765-E3EF-4191-BFE0-5388850206F5-19742-0000F776A4C10AF9/屏幕快照 2018-10-27 11.16.25.png]
3.3 操作符
3.1常用操作符
Scala中没有操作符,只是一操作符的格式去进行方法调用
//算术运算符 +、-、* 、/、% //关系操作符
> < >= <= != == //逻辑操作符 && || ! //位操作符 | & ^ ~ << >> >>> ~:补运算符,是一元的,具有‘翻转’位的效应。
>>:带符号右移。正数右移高位补0,负数右移高位补1。
>>>:无符号右移。无论是正数还是负数,高位通通补0。 //赋值运算符 = += -= *= /= %= <<= >>= &= ^= |=
运算符优先级:
[image:4E306E23-3709-4A45-9517-3C2464B754B8-19742-0000F79EB1A064CA/屏幕快照 2018-10-27 11.19.22.png]
3.2 操作符注意点
- a+b 等价于 a.+(b)
- Scala 中没有++ , —- 可以用+=,-=代替
3.操作符都是方法的重载,是方法的调用
条件表达式
If/else 表达式有值,这个值就是跟在if 或者 else 之后的表达式的值
object ConditionDemo {
def main(args:Array[String]){
val y = if(x > 0) 1 else -1
println(z)
//执行结果为 1
//支持混合表达式
//返回类型是Any
val z=if(x>0) "success" else -1
println(z)
//执行结果为 success
//如果确实else,相当于if(x>2) 1 else ()
//返回类型是AnyVal
//如果进行类型判断和转换,可以使用:
//val b =if (m.idInstanceOf[Int]) m.asInstanceOf[Int] else 0
val m =if(x>2) 1
println (m)
//执行结果为 ()
//在scala中,每个表达式都有值,scala中有一个Unit类,写作()
//相当于java中的void
val n =if(x>2) 1 else ()
println(n)
//执行结果为 ()
//if嵌套
val k = if(x<0) 0 else if(x>1) 1 else -1
println(k)
//执行结果为 1
}
}
Scala的条件表达式比较简洁 例如:
注意:
- 每个表达式都有一个类型
- 混合型表达式,结果是Any或者AnyVal
- 条件表达式有值
- scala没有switch语句
3.5 块表达式
object BlockExpressionDemo { def main(args: Array[String]){
var x = 0
//在scala中,{}中可以包含一系列表达式,块中最后一个表达式的值就是块的值
val res = {
if (x < 0) { -1 } else if (x >= 1) {
1 } else {
"error" }
}
println(res)
//执行结果为 error
val x0 = 1 val y0 = 1 val x1 = 2 val y1 = 2 val distance = {
val dx = x1 - x0
val dy = y1 - y0
Math.sqrt(dx*dx+dy*dy) }
println(distance)
//执行结果为 1.41421135623730951
//块语句,最后一句是赋值语句,值是unit类型的
var res2 = {
val dx = x1 - x0
val dy = y1 - y0
val res = Math.sqrt(dx*dx+dy*dy)
}
println(res2)
//执行结果为 ()
}
}
注意:
- 块表达式的值是最后一个表达式的值
- 赋值语句的值是Unit类型的
3.6 循环
在scala中有for 循环和while循环 用for循环比较多
For 循环语法结构:for(i<-表达式/数组/集合)
While (条件语句){表达式}
do{表达式}while()
object ForDemo{
def main(args:Arrays[String]){
//每次循环将区间的一个值赋给i
for(i<- 1 to 10 )
println(i)
for(i<- 1 until 10)
println(i)
//for i<- 数组
val arr= Array("a","b","c")
for(i<- arr)
println(i)
val s ="hello"
for (i<- 0 until s.length)
println(i)
}
//或者
//for(c <- s)println(c)
//或者
//for(i<- 0 until s.length)
//println(s.charAt(i))
//使用了隐式转换,把字符串变成一个arrayCharSequence
//}
//高级for循环
for(i<- 1 to 3;j<- 1 to 3 if i !=j )
print((10*i+j)+"")
//for 推导式,如果for循环的循环体是以yield开始,则该循环会构建出一个家和或者数组,每次迭代的时候生成其中的一个值
val v =for(i<- 1 to 10)yield i*10
println(v)
//延伸,更加简洁的使用
//也可以借助函数由初始值生成一个新的数组
val arr1=Array(1,2,3,4,5,6,7,8)
val arr2 = arr.map(_*10)
val arr3 = arr3.filter(_%2==0)
}
}
Scala中如何跳出循环
1.基于Boolean类型的控制变量
var flag =true
var res =0
for(i<- 0 until 10 if flag)
res +=i
println("res = "+res)
if(i == 5)flag = false
Scala 里面竟然没有break 和 continue关键字 。其实不是这样的,scala中推荐使用函数式的风格解决break 和 continue功能,而不是一个关键字
//需要导入包
improt util.control.Break._
//break例子
object scalaTest {
def main(args:Array[String]):Unit = {
//break例子
breakable(
for(i<- 0 until 10)
if(i==5){
break()
}
println(i)
)
}
}
//continue 例子
import util.control.Breaks._
object scalaTest{
def main (args: Array[String]): Unit = {
//break 例子
for(i<- 0 until 10){
breakable(
if(i==5){
break()
}
println(i)
)
}
}
上一篇: python究竟要不要使用多线程
下一篇: Scala基础教程 -- 类