1. 声明变量、常量
var 声明变量 格式:var 常量名 : 类型 = 值
val 声明常量 格式:val 常量名 : 类型 = 值
2. 常用类型
Any :是所有类的超类,相当于 Java 中的 Object,AnyVal 和 AnyRef 是它的两个子类
AnyVal :是所有值类型的基类,它描述的是值,而不是代表一个对象
AnyRef :是所有引用类型的基类。除了值类型,所有类型都继承自AnyRef
7种数值类型:Byte、Char、Short、Int、Long、Float、Double
AnyVal包含7个数值类型、1个Boolean类型、1个Unit类型
Scala编译器会自动推断变量的类型,必要时可以指定类型
scala> var i=1
i: Int = 1
scala> var i=true
i: Boolean = true
scala> var i:String = "abc"
i: String = abc
数据类型都是对象,+-*/%等都是方法
scala> val a=2
a: Int = 2
scala> val b=4
b: Int = 4
scala> a+b
res5: Int = 6
scala> a.+(b)
res6: Int = 6
3. 条件表达式
如果 if-else 语句缺 else ,则相当于 else ()
在scala中每个表达式都有值,scala中有个 Unit 类,用作不返回任何结果的方法的结果类型,相当于Java中的void,Unit只有一个实例值,写成()
scala> val x=1
x: Int = 1
scala> var y = if(x>0) 1 else 0
y: Int = 1
scala> var y = if(x>0) 1 else "abc"
y: Any = 1
scala> var y = if(x>0) 1 else true
y: AnyVal = 1
scala> var y = if(x>1) 1
y: AnyVal = ()
scala> var y = if(x>1) 1 else ()
y: AnyVal = ()
# if-else-if语句
scala> var y = if(x>1) 1 else if(x>0) 0 else -1
y: Int = 0
4. 块表达式
定义变量时用 {} 包含一系列表达式,其中块的最后一个表达式的值就是块的值
scala> val a = 3
a: Int = 3
scala> val b = {
| val c = a*3
| val d = c+1
| d}
b: Int = 10
5. 循环
- for循环语法结构:for(i <- 表达式 / 数组 / 集合)
表达式 1 to 10 返回一个Range(区间)
scala> var a1 = Array(1,2,3)
a1: Array[Int] = Array(1, 2, 3)
scala> for(i <- a1) println(i)
1
2
3
scala> for(i <- a1) println(i*10)
10
20
30
scala> 1 to 10
res9: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> 1 until 10
res10: scala.collection.immutable.Range = Range(1, 2, 3, 4, 5, 6, 7, 8, 9)
scala> for(i <- 1 to 10) print(i + " ")
1 2 3 4 5 6 7 8 9 10
scala> for(i <- 1 until 10) print(i + " ")
1 2 3 4 5 6 7 8 9
scala> for(i <- a1) yield i*10
res13: Array[Int] = Array(10, 20, 30)
scala> a1
res14: Array[Int] = Array(1, 2, 3)
scala> a1.map(x => x*10)
res15: Array[Int] = Array(10, 20, 30)
scala> a1.map(_*10)
res16: Array[Int] = Array(10, 20, 30)
scala> a1
res17: Array[Int] = Array(1, 2, 3)
object ForTest {
def main(args: Array[String]): Unit = {
// 每个生成器都可以带一个条件,注意:if前面没有分号
for (i <- 1 to 3; j <- 1 to 3 if i != j)
print(i * 10 + j + " ")
println()
// for推导式:如果for循环的循环体以yield开始,则该循环会构建出一个集合
// 每次迭代生成集合中的一个值
val a = for (i <- 1 to 5) yield i * 10
println(a)
}
}
12 13 21 23 31 32
Vector(10, 20, 30, 40, 50)
- while循环
scala> var a = 10
a: Int = 10
scala> while(a>5){
| print(a + " ")
| a = a - 1
| }
10 9 8 7 6
- do-while循环
scala> var a = 10
a: Int = 10
scala> do {
| print(a + " ")
| a = a - 1
| } while(a>5)
10 9 8 7 6
6. 方法和函数
- 方法
方法由def关键字定义。def后面跟着一个名字、参数列表、返回类型和方法体。方法体的最后一个表达式就是方法的返回值。方法的返回值类型可以不写,编译器可以自动推算出来,但是对于递归函数,必须指定返回值类型。
scala> def ff(n:Int) = {
| if(n<1) 1
| else ff((n-1)*n)}
<console>:14: error: recursive method ff needs result type
scala> def ff(n:Int):Int = {
| if(n<1) 1
| else ff((n-1)*n)}
ff: (n: Int)Int
scala> ff(5)
res1: Int = 1
- 函数
函数是带有参数的表达式。=>的左边是参数列表,右边是一个包含参数的表达式。
scala> (x:Int,y:Int)=>x+y
res2: (Int, Int) => Int = <function2>
# 给函数起名字,Java中思想叫做引用
scala> var ff = (x:Int,y:Int) => x+y
ff: (Int, Int) => Int = <function2>
scala> ff(2,3)
res3: Int = 5
# 函数可以不带参数
scala> val ff = () => 2
ff: () => Int = <function0>
- 方法和函数的区别
在函数式编程语言中,函数是“头等公民”,它可以像任何其他数据类型一样被传递和操作,函数是一个对象,继承自FunctionN。函数对象有 apply、curried、toString、tupled这些方法
scala> def m1(x:Int,y:Int) = x*y
m1: (x: Int, y: Int)Int
scala> m1(2,3)
res0: Int = 6
scala> def m2(f:(Int,Int)=>Int)=f(2,4)
m2: (f: (Int, Int) => Int)Int
scala> val f = (x:Int,y:Int) => x+y
f: (Int, Int) => Int = <function2>
scala> m2(f)
res1: Int = 6
- 将方法转换成函数(神奇的下划线)
如果想把方法转换成一个函数,可以用方法名跟上下划线的方式。
scala> def m1(x:Int,y:Int) = x*y
m1: (x: Int, y: Int)Int
scala> m1(2,3)
res0: Int = 6
scala> def m2(f:(Int,Int)=>Int)=f(2,4)
m2: (f: (Int, Int) => Int)Int
scala> val f = (x:Int,y:Int) => x+y
f: (Int, Int) => Int = <function2>
把函数作为参数传递给方法,这时候的函数跟普通的value一样,作为参数传递
scala> m2(f)
res1: Int = 6
scala> val ff = m1 _
ff: (Int, Int) => Int = <function2>
scala> val ff = m1
<console>:12: error: missing argument list for method m1
Unapplied methods are only converted to functions when a function type is expected.
You can make this conversion explicit by writing `m1 _` or `m1(_,_)` instead of `m1`.
val ff = m1
^
将方法转换成函数
scala> m2(m1 _)
res2: Int = 8
隐式转换
scala> m2(m1)
res3: Int = 8
并行计算
scala> (1 to 5).foreach(println(_))
1
2
3
4
5
scala> (1 to 5).par.foreach(println(_))
4
5
2
1
3
scala> val l1 = List(1,2,3,4,5,6)
l1: List[Int] = List(1, 2, 3, 4, 5, 6)
scala> l1.fold(0)(_+_)
res2: Int = 21
scala> l1.fold(10)(_+_)
res3: Int = 31
scala> l1.par.fold(10)(_+_)
res4: Int = 51
scala> l1.par.fold(10)(_+_)
res5: Int = 71