scala 学习入门

基本类型

大部分都能隐式转换,Byte、Short需要显式指定

1
2
val little : Byte = 3
val little:Short = 3

char、String支持\转义

1
2
val a = 'a'    //char = 'a'
val str = "hello \101" //String=hello A

带小数点的默认为Double,以F结尾表示Float

1
2
val pi = 3.14F
val pi = 3.14 // double

定义函数

1
2
var fun = (v : Int) => v + 1  //匿名函数赋值给一个变量
def addOne(v : Int) : Int = v + 1 //非匿名函数

控制结构

if表达式

1
2
3
val filename = 
if (!args.isEmpty) args(0)
else "default.txt"

while循环

1
2
3
4
5
6
7
8
9
10
11
//计算最大公约数
def gcdLoop(x : Long,y: Long) : Long = {
var a = x
var b = y
while (a != 0){
val temp = a;
a = b % a;
b = temp
}
b
}

do…while

1
2
3
4
5
var line = ""
do {
line = readLine()
println("read:"+line)
}while(line != "")

for表达式

1
2
for( i <- 1 to 4)
println("Iteration "+ i)

try…catch

1
2
3
4
5
6
7
8
9
10
11
12
13
def g() : Int = {
try{
1/0
}catch{
case ex: ArithmeticException => {
ex.toString
2
}
case _ :Throwable => 3
}finally{
println("finally")
}
}

基本数据结构

数组Array:可修改,通过括号()来引用

1
2
val greeting = new Array[String](2)
greeting(0) = "hello"

列表List:只读

1
2
val numbers = List(1,2,3,4)
numbers(0)

元组Tuple:只读,与List类似,可以是不同元素,下标从1开始

1
2
3
val hostPort = ("localhost",80)
hostPort._1
hostPort._2

集合Set:只读,没有重复的元素

1
Set(1,1,2)

映射Map:

1
2
3
4
5
6
7
val m = Map(1 -> "one",2 -> "two")
m(2)
//创建可写版本
val m = scala.collection.mutable.Map[Int,String](1 -> "one",2 -> "two")
m += (3 -> "three")
m(4)="four"
m -= 2

定义class

1
2
3
4
5
class Hello( _a : Int) {
private val a = _a;
println("initializing...(" + _a + “) ”);
def add( b : Int) : Int = a + b;
def this() = this(0);

继承

1
2
3
class Hello2(a : Int) extends Hello(a) {
def add(b : Int, c : Int) : Int = a + b+ c;
}

单实例对象

scala 不支持static变量、成员,但提供了单例对象,用object来定义

1
2
3
4
5
6
7
8
object Timer {
var count = 0;
def currentCount() : Long = {
count += 1
count
}
}
Timer.currentCount()

单例对象可以和类具有相同的名字,放在同一个源文件,可以相互访问彼此的private方法和变量。

1
2
3
4
class Bar(foo : String)
object Bar{
def apply(foo : String) = new Bar(foo);
}

匿名函数

1
2
3
(x:Int) => x+1
var incr = (x:Int) => x+1
incr(10)

匿名函数作为参数

1
2
3
4
val someNumbers = List(1,3,-2,0)
someNumbers.filter( x => x > 0 )
//如果匿名函数的参数只被使用一次,可以直接写函数体,用_代替一个参数
someNumbers.filter(_ > 0)

函数嵌套

1
2
3
4
5
6
7
8
import scala.io.Source
def processFile(filename : String){
def processLine(line : String){
println(line)
}
Source.fromFile(filename).getLines.foreach(processLine);
}
processFile("t.scala")

部分应用函数

函数的参数可以分步提供

1
2
3
4
def adder(m : Int,n : Int, z : Int) : Int = m + n + z
val adder2 = adder(2,_:Int,_:Int) //部分应用函数,只输入参数2,用_代替没有准备好的另一个参数
val adder3 = add2(3,_:Int)
adder3(4) //9

柯里化函数currying

1
2
3
4
5
6
7
8
9
10
11
//非柯里化函数
def plainSum(x : Int,y : Int) = x + y;
plainSum(1,2)
//柯里化
def curriedSum(x:Int)(y:Int) = x + y
//可以一次输入两个参数来调用
curriedSum(1)(2)
val onePlus = curriedSum(1)_ //使用了部分应用函数符号_
onePlus(2)
val twoPlus = curriedSum(2)_
twoPlus(3) //5

1
2
3
4
5
package org.scala.example
object Color{
val BLUE = "Blue"
val Green = "Green"
}

模式匹配

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
times match{
case 1 => "one"
case 2 => "two"
case _ => "some other"
}
//对象匹配
def bigger(o : Any) : Any = {
o match {
case i : Int if i > 0 => i - 1
case i : Int => i + 1
case d: Double if d > 0.0 => d - 0.1
case d: Double => d + 0.1
case text:String => text + "s"
}
}
val v42 = 42
// print Not 42
Some(3) match {
case Some(`v42`) => println("42")
case _ => println("Not 42")
}

scala应用程序

入口:单实例对象,内部必须有一个main方法,main有且仅有一个Array[String]的参数,并且返回Unit

1
2
3
4
5
6
7
// Hello.scala
object Hello{
def main(args : Array[String]) {
for (arg <- args)
println("hello " + arg)
}
}

运行:

1
2
3
4
> scala Hello scala spark
//print
hello scala
hello spark

闭包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
scala> var more =1
more: Int = 1
scala> val addMore = (x:Int) => x + more
addMore: Int => Int = <function1>
scala> addMore (100)
res1: Int = 101
//addMore为闭包,引用了外部变量more。当这个自由变量发生变化时,Scala 的闭包能够捕获到这个变化,因此 Scala 的闭包捕获的是**变量本身**而不是当时变量的值。
scala> more = 9999
more: Int = 9999
scala> addMore ( 10)
res2: Int = 10009

如果变量在闭包在发生变化,也会反映到函数外面定义的闭包的值。比如:
scala> val someNumbers = List ( -11, -10, -5, 0, 5, 10)
someNumbers: List[Int] = List(-11, -10, -5, 0, 5, 10)
scala> var sum =0
sum: Int = 0
scala> someNumbers.foreach ( sum += _)
scala> sum
res4: Int = -11