scala基础语法
声明值和变量
scala使用val或者var声明变量
var/val 变量名[:变量类型]=变量值
val定义的变量,值是不可变的,是一个常量
var a=10
var b="hello"
val author="upuptop"
变量类型可以省略,解析器会根据值判断,val和var声明变量时都必须初始化。尽可能的使用不可变变量
常用类型
- Boolean:true或者false
- Byte:8位 有符号
- Short:16位 有符号
- Int:32位 有符号
- Long:64位 有符号
- Char:16位 无符号
- Float:32位,单精度浮点数
- Double:64位 双精度浮点数
与java不同,scala不区分引用类型和基本类型,所以这些类型都是对象,可以调用相应的方法。
Scala没有强制类型转换,需要通过方法进行类型的转化
scala中所有的值都是类对象,所有的类,包括值类型,都最终继承自根类型:Any。
特殊:
Null
是所有引用类型的子类型,只有一个实例对象,null
类似于java中null的引用。Nothing
可以作为没有正常返回值的方法的返回类型。是所有类型的子类型Unit
类型用来标识过程,也就是没有明确返回值的函数。类似于java中的void。只有一个实例对象()
这个实例没有实质意义
操作符
+ - * / %
可以完成和java相同的工作。但是他们都是方法。
下面代码,第二个操作就相当于1调用了+()方法并传递了2为参数
scala> 1+2
res0: Int = 3
scala> 1.+(2)
res1: Int = 3
Scala中没有++
--
操作符,需要通过+=
-=
实现
调用函数和方法
除了方法,Scala还提供了函数,比如数学函数:
调用函数 导入包
import 包名._
注:_ 在这里是通配符相当于java中的*
scala> import scala.math._
import scala.math._
scala> sqrt(3)
res2: Double = 1.7320508075688772
调用静态方法
Scala中没有静态方法,一般通过到单例对象或者伴生对象进行实现
scala> BigInt.probablePrime(100,scala.util.Random)
res3: scala.math.BigInt = 719354201634616441856306472377
调用对象的方法
String的去重方法:
scala> "upuptop".distinct
res4: String = upto
apply与update方法
apply
方法调用时可以省略方法名。用于构造和获取元素
scala> var a = "hello".apply(4)
a: Char = o
scala> var c = "hello"(4)
c: Char = o
update
方法调用时可以省略方法名。用于元素的更新
scala> var arr = Array(1,2,3,4)
arr: Array[Int] = Array(1, 2, 3, 4)
scala> arr.update(0,5)
scala> arr
res10: Array[Int] = Array(5, 2, 3, 4)
scala> arr(0)=0
scala> arr
res12: Array[Int] = Array(0, 2, 3, 4)
控制结构和函数
java中把表达式和语句当成两个不同的东西,表达式有值,语句没有值,只是控制结构,在Scala中几乎所有的语法结构都有值。
if……else表达式
scala> var x = 10
x: Int = 10
scala> var s = if(x>9) 1 else -1
s: Int = 1
没有三元运算,不需要
if表达式的返回值类型取决于最后一条语句,如果if和else的返回值类型不一致那么就返回Any类型。
行尾不需要写分号,只要能够从上下文判断出语句的终止即可。但是如果在单行中写多个语句,需要使用分号分割。
while表达式
Scala提供和java一样的while和do循环。while语句没有返回值
scala> while(i<=100){
sum+=i
i+=1
println(sum)
}
scala> do{
i+=1
sum+=i
}while(i<100)
Scala没有提供break和continue语句来退出循环,如果需要break,可以通过下面方法进行实现
- 使用Boolean类型的控制变量
- 使用嵌套函数,从函数中return
- 使用Breaks对象中的break方法。
for表达式
scala> for(i<- 1 to 100; if i <= 100){
sum+=i
}
scala> sum
res31: Int = 5050
i<- 1 to 100
:i从1 到100
变量名 <- 集合
这样的表达式也被称为生成器表达式,该表达式会基于集合生成单独的数值
if i <= 100
成为保护式(守卫)可以由一个或者多个
for推导式可以引入变量
scala> for(i<- 1 to 3;fff = 4 - i )print(fff+" ")
3 2 1
for循环的返回值
yield
关键字
scala> var resuu = for(i<- 1 to 3;fff = 4 - i ) yield fff
resuu: scala.collection.immutable.IndexedSeq[Int] = Vector(3, 2, 1)
{}
和()
for 后面使用{}
表达式之间可以不使用分号,换行,使用()
必须使用分号进行分割
scala> for{
i <- 1 to 3
from = 4 - i
j <- from to 3
}
print((10*i+j)+" ")
13 22 23 31 32 33
函数
定义
def 函数名(参数名:类型...)[:返回值类型] = 函数体
def 函数名(参数名:类型...)[:返回值类型] {
函数体
}
递归函数:求阶乘,递归函数必须有返回值
def recursiveFuc(x: Int): Int = if (x == 0 || x == 1) 1 else x * recursiveFuc(x - 1)
println(recursiveFuc(5))
参数默认值函数:
def sum(a: Int = 1, b: Int) = a + b
println(sum(b = 1))
变长函数/可变参数
def sum(a: Int*): Int = {
var res = 0
for (i <- a) res += i
// 相当于 return res
res
}
println(sum(1,2,3,4,5))
过程
不返回值得函数叫做过程,返回类型是Unit,没有等号
def noRet(name: String): Unit = {
println(s"hello ${name}")
println("hello" + name)
}
noRet("upuptop")
懒值
当val被声明为lazy
时,它的初始化将被推迟,知道我们开始使用的时候才会取值。
- 用于初始化开销比较大的语句
- 可以解决循环依赖问题
- 是开发懒数据结构的基础
lazy val a = 100
异常
抛出异常
抛异常使用throw
关键字,不需要在方法或者函数上声明异常
所有的异常都是Throwable的子类型。throw表达式也是有类型的,是nothing
def fun(a: Int, b: Int): Int =
if (b == 0) {
throw new Exception("/ by zore")
} else {
a / b
}
try {
println(fun(1, 0))
} catch {
case e: Exception => println(s"出现异常${e}")
} finally {
println("finally")
}
打印结果:
出现异常java.lang.Exception: / by zore
finally
res0: Unit = ()