标识符
val ++= 1 // 编译器对++做了特殊处理,查看.class文件
val +-= 1
val @#$ = true
val _ = "abc" // _有特殊含义
val a = "abc"+_ // 返回的是function<>
操作符
- scala中没有++、--操作符,通过+=、-=实现
n = n + 1
n += 1
// java
byte i =1;
i+=1; // ok
i=i+1; // error 提升了i的类型为int
// scala
var i:Byte = 1
i+=1 // error i类型被提升
关系运算符
var b = true
if(b = 10) // error
println(b = 10) // 返回()
val flag = true
val result:Unit = if(flag){}
val result:Any = if(flag){
"abc"
}
流程控制
- 没有switch(模式匹配)
- 没有continue(守卫)
- 没有break(Breaks.break()抛异常)
for(i <- 1 to 3) // 1-5 Range.inclusive(self, end)
for(i <- 1 until 3) // 1-2 Range(self, end)
for(i <- Range(1,5,2)) // Range(self, end, step)
for(i <- 1 to 10 if i%2 == 0) // 循环守卫,替代continue
for(i <- 1 to 10;j = i) // 循环中定义变量
for{i <- 1 to 10
j = i // 表达式有多行时for使用{}
}
// 把每次循环的结果放到一个集合里,输出结果:Vector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val resutl: immutable.IndexedSeq[Int] = for(i <- 1 to 10) yield i
Breaks.breakable {
for (i <- 1 to 10) {
if (i == 5) Breaks.break()
println(i)
}
}
函数式编程
- 面向对象:将问题拆解成一个一个小的问题,形成对象,操作对象
- 函数式编程:关心问题的解决方案,函数封装了解决方案的步骤,操作函数(入参/出参)
- method:从属于类,通过类调用
- function:独立声明,独立使用
- method无法作为参数传递,function可以
- 函数没有重载,作用域内不能重名
- 递归函数必须显示声明返回值,无法通过类型推断
def fun(): Unit = {
return "AA" // return无效,返回()
}
def fun(): String = {
"AA"
}
def fun = "AA" // 最简写法,如果函数小括号省略,调用时也不能加小括号
()->{println("AA")} // 匿名函数
def fun(args:String*): Unit = {} // 可变参数
def fun(age:Int=10,name:String): Unit = {} // 默认参数,age可不传,参数匹配从左到右,注意顺序
fun(age=1,name="AA") // 带名参数
// 函数返回值是函数
def f1(i: Int): Int => Int = {
def f2(j: Int): Int = {
i + j // 闭包:改变i的声明周期
}
f2 _
}
println(f1(1)(3))
// 柯里化
def f3(i: Int)(j: Int): Int = {
i + j // 闭包
}
println(f3(1)(3))
// 函数作为参数传递,f(声明类型不声明变量)
def fun(i:Int,j:Int,f:(Int,Int)=>Int):Int={
f(i,j)
}
println(fun(1,2,(x,y)=>{x+y})) // 匿名函数
// 函数的返回值是函数
def f1(x: Double): Double => Double = {
def f5(y: Double): Double = {
x * y
}
f5 _
}
// f1()的简写
def f2(x: Double): Double => Double = {
y: Double => x * y // 匿名函数
}
// f1() f2()柯里化过程
def f3(x: Double)(y: Double): Double = {
x * y
}
异常处理
try{
}catch{
case ex:xxxException => ...
case ex:RumtimeException => ...
}finally{
}
package
- 同一个源文件中可以声明多次package
- 源码中的类所在的路径不需要和包路径相同
- 所有的语法都可以嵌套
// 以下等同于package com.foo.bar,只是拆分为多行
package com
package foo
package bar
package p3
package p1{
// package中可以声明类,但无法声明变量、函数
class User(){}
// 包对象解决package中无法声明变量和函数
package object p{
val a:String = _
def fun(): Unit = {
}
}
package p2{
class User{} // p1.p2包
}
}
class User{} // p3包中
import
- 放在任意地方
- java中的import是导入类,scala是导包和类·
import java.util._ // 导入包下的所有类
import java.util.{ArrayList,Date,List} // 导入包下的多个类
import java.util.{Date=>_} // 包下Date类不导入,其它类都导入
import java.sql.Date // 同时导入util、sql中的Date,util.Date不导入,使用sql.Date
field
class User{
// _初始化为默认值
var name:String = _ // var 默认是public权限,setter/getter
var age:Int = _
private var address:String = _ // private setter/getter
val city:String = _ // 变量是final不能修改,public getter
}