Scala基础
1.变量的声明
- 1.1 变量声明语法
val | var 变量名 [:变量类型] = 变量值,如:
val age:Int = 123
val height = 123.3
var weight:Double = 123.3
var price:Float = 123.4f
var isTrue:Boolean = true
- 1.var表明变量是可变的,val表明变量是不可变的(与java的final一样);
- 2.scala语法是变量名在前,数据类型在后,与java相反;
- 3.scala数据类型首字母大写;
- 4.数据类型可以省略,scala会自动推断;
- 5.scala每句结尾无需加分号,除非一行有多句表达式;
- 6.变量声明需要初始化;
- 1.2 数据类型
- 1.scala万物皆对象,包括Int、Float等,因此Int等数据类型可以直接使用方法;
val age:Int = 123
age.toString
- 2.所有的数据类型均来自于共同的父类Any类;
- 3.Any类有两个子类AnyVal和AnyRef;
- 4.AnyVal为值类型,AnyRef为引用类型;它们的子类有一个共同的子类Nothing
AnyVal | AnyRef |
---|---|
Double | collections |
Float | scala classes |
Long | java classes |
Int | Null(上述三种子类的子类),它只有一个实例值null,可以给任意的AnyRef |
Short | |
Byte | |
Boolean | |
Char | |
StringOps | |
Unit(等价于void) |
- 5.char用’ ';string用" "
- 6.隐式(implicit)类型转换:由低精度向高精度转换;高精度无法向低精度自动转换,需要使用强制类型转换;
//强制类型转换
int num = (int)2.7 //java
val num:Int = 2.7.toInt //scala
- 7.值类型转string,可直接在后面加空字符串
val num:Int = 123
var value:String = num + "";
2.流程控制
- 2.1 if-else
- 条件的返回值必须是Boolean类型,不能是零或非零的值类型
if(条件){
}else{
}
if(条件){
}else if(条件){
}
- if-else是有返回值的(scala任意表达是均有返回值),返回值取决于if-else执行的最后一个语句的返回值
val height = 12
val res = if(height > 12){
9 + 10
}else{
123
"okokok"
"yyy"
}
println(res)//输出"yyy"
//当执行的最后一行的返回值是Unit(即无返回值类型),则返回()
val height = 123
val res = if(height > 12){
9 + 10
println("okok")
}else{
123
"okokok"
"yyy"
} //此时res为()
- scala没有switch,改用match-case
3.循环
- 3.1 增强for循环
- scala没有类似于for(int i = 1; i < 10;i++)这样的for循环,取而代之的是增强for循环,即对一个集合中的元素进行遍历
// x to y 产生[x,y]内的所有整型元素,左右均闭
// x until y [x,y) 左闭右开
for(i <- 1 to 10){
println(i + "")
}
var lst = list("xxx",123,12.4)
for(item <- lst) println(item)
- 3.2 for循环守卫
- 守卫即给for循环增加遍历条件
for(i <- 1 to 10 if i%2 == 0) println(i) //只输出偶数
//等价于
for(i <- 1 to 10){
if(i %2 == 0) println(i)
}
- for循环引入变量
for(i <- 1 to 10;j = i + 123) println(j)
//等价于
for(i <- 1 to 10){
j = i + 123
println(j)
}
- for循环嵌套
for(i <- 1 to 10;j <- 1 to 2) print(i + "," + j)
//等价于
for(i <- 1 to 10)
for(j <- 1 to 2) print(i + "," + j)
- 循环返回值
val res = for(i <- 1 to 10) yield{
代码块
}
res为一个Vector,其元素为每一次遍历的返回值,即代码块执行的最后一句代码的返回值
- 3.3 while循环
- 先判断后执行
var i = 3
while(i < 10){
i += 1
println(i)
} //while没有返回值
- 3.4 do-while循环
- 先执行后判断,至少执行一次
do{
代码块
}while(条件)
4.break与continue
scala没有内置的break和continue
- 4.1 break
import scala.util.control.Breaks.break
var i = 3
while(i < 10){
i += 1
println(i)
break()
}
//该break()函数实质上是扔出异常Exception in thread "main" scala.util.control.BreakControl,且并未进行异常值捕获,非真正的跳出循环,因此无法实现跳出循环的功能
//为了满足跳出循环的需求,scala进一步封装了breakable函数
import scala.util.control.Breaks.breakable
breakable {
var i = 3
while (i < 10) {
i += 1
println(i)
}
}
//breakable是一个高阶函数(即将函数作为参数),底层实现实质上是完成了上述break的异常捕获
- 4.2 continue
- scala没有continue,需要使用for循环守卫或if-else实现
for( i <- 1 to 10 if i % 2 != 0){
...
}
5.函数
- 5.1 函数的三种定义方式
- def 函数名(参数名1:数据类型,…) : 返回值类型 = {代码块}
def sum(n1:Int,n2:Int):Int = {
return n1 + n2
}
//1.可以是无参函数
//2.返回值可以通过return指定,当无return关键字时,将函数最后一句执行的代码的返回值当作函数的返回值
//3.返回值类型可以省略,def sum(n1:Int,n2:Int)={}会进行自动类型推导 递归函数必须指定返回值类型
//4.如果连3中的=也省略,即def sum(n1:Int,n2:Int){},则无返回值,即便函数中给出返回值,等价于def sum(n1:Int,n2:Int):Unit={}
- val 函数名:(参数1类型,…) => 返回值类型 = {(参数1,…) => {函数体}}
val sum:(Int,Int) => Int = {(n1,n2) => n1 + n2}
- 匿名函数 (参数1:类型,…) => {函数体}
(n1:Int,n2:Int) => {n1 + n2}
- 函数注意事项
- 如果一个参数在函数体中仅仅出现一次,则该参数可以用下划线占位表示
val add = (_:Int) + (_:Int)
- 函数的形参默认时val类型
- 参数支持可变个数
def sum(n:Int,args:Int*) = {
var s = n
for(i <- args) s += i
s
}
//调用 sum(1,2,3,4,5)
//可变参数必须放在参数末尾
//函数接受到的可变参数其实是sequence类型,可用for获取
- 惰性函数
- 惰性函数在被调用时不会马上执行,只有当惰性函数的返回值被第一次引用时才会真正执行,关键词lazy
def sleepFunc()={
println("sleep start...")
123
}
def printFunc(): Unit ={
println("print start ...")
}
lazy val result = sleepFunc()
printFunc()
print(result)
//printFunc会先与sleepFunc被调用
//lazy 只能修饰al类型的