1. 程式人生 > >[scala]學習筆記一

[scala]學習筆記一

一、scala的特點:

1.Scalable程式語言 (可伸縮的,既可以是指令碼語言,又可以為大型伺服器所使用)
2.純正的面向物件的語言
3.函式式語言
4.無縫的Java互操作

二、scala函式式的程式設計思想:

1.純函式,不具有副作用
2.引用透明
3.函式是一等公民:一切都是計算,函數語言程式設計中只有表示式和變數!函式也是表示式

三、變數

1.val:定義常量(immutable variable),同java的final,給值後就不能再改變
2.var:定義變數(mutable variable),可以改變賦值的內容
3.lazy val:定義的時候不求值,在第一次使用的時候才會求值,即第一次操作時才會延遲載入
建議使用val

scala> lazy val a=1
a: Int = <lazy>
scala> a
res0: Int = 1

四、資料型別

1.數值型別:Byte、Short、Int、Long、Float、Double
2.布林型別:true、false
3.字元型別:Char
4.Unit型別:函式無返回值時,定義為Unit型別
5.Nothing和None
6.String:構建於Java的String之上,新增了字串插值的特性

scala> val string="Nina"
string: String = Nina
scala> s"my name is ${string}"
res1: String = my name is Nina

五、函式

函式/方法的定義:

//主函式
def main(args: Array[String]): Unit = {
    println(add(3,4))
    println(three())
    println(three)            //函式沒有形參的話,可以直接呼叫函式名,不需要加小括號
    hello()
}
def add(x:Int,y:Int):Int={
    x+y
}

def three()=1+2           //方法體只有一行,不需要加大括號

def hello(): Unit ={             //Unit表示函式沒有返回值
    println("hello world")
}

六、引數

1.預設引數:在函式定義時,允許指定引數的預設值

def main(args: Array[String]): Unit = {
    sayName()				      //不指定引數呼叫
    sayName("Jack"))         //指定引數呼叫
}
def sayName(name:String="Nina"): Unit ={           //預設引數是Nina
    println("hello, "+name)
}

結果:
hello, Nina
hello, Jack

2.命名引數:可以更改某一函式中引數的位置,但需要指明該函式的名稱,不太建議

3.可變引數:引數的個數可以改變

def main(args: Array[String]): Unit = {
    println(sum(1,2))         //可變引數,函式中引數的個數不同,都可以呼叫sun()函式進行計算
    println(sum(1,2,3,4))
}
def sum(numbers:Int*)={					//Int後的*用來匹配可變的引數值
    var result:Int=0
    for(number:Int<-numbers){
      result+=number
}
    result
}

結果:
3
10

七、if表示式、for表示式、try表示式、match表示式

1.if表示式

scala> val x=1
x: Int = 1
scala> if (x>0) true else false
res2: Boolean = true

2.for表示式

val arr=Array("Nina","Jack","Linda")			//定義了一個Array

arr.foreach(name=>println(name))  			//迴圈打印出arr中內容的一種方法

for(name<- arr)   					//迴圈打印出arr中內容的另一種方法
          println(name)

3.try表示式:try()、catch()、finally()

try{
      Integer.parseInt("dog")
      }catch{
         case _ =>0
      }finally{
         println("always be printed")
}

結果:
always be printed
res3: Int = 0

4.match表示式:同Java中的switch

scala> x match{
      case 1 =>"one"
      case 2=>"two"
      case 3=>"three"
      case _=>"default"
 }

結果:
res4: String = two

八、求值策略

1.call by value:def foo(x:Int)=x
2.call by name:def foo(x:=>Int)=x
call by value 會對函式的形參先求值

//call by value
def foo(x:Int,y:Int)=x*x
結果:foo(3+4,8)->foo(7,8)->7*7->49

//call by name
def foo(x:=>Int,y:=>Int)=x*x
結果:foo(3+4,8)->(3+4)*(3+4)->7*(3+4)->7*7->49

九、柯里化

把具有多個引數的函式轉換成一條函式鏈,每個節點上是單一引數

//普通
def add(x:Int,y:Int)=x+y
//柯里化語法
def add(x:Int)(y:Int)=x+y

十、遞迴函式

在函數語言程式設計中沒有迴圈,需要通過遞迴來實現迴圈
遞迴會使用到棧,容易溢位,因此改進推出了尾遞迴函式
尾遞迴函式:
尾遞迴函式中所有遞迴形式的呼叫都出現在函式的末尾
當編譯器檢測到一個函式的呼叫是尾遞迴時,它就覆蓋當前的活動記錄,而不是在棧中建立一個新的,從而避免了棧溢位的問題

scala> @annotation.tailrec			//宣告是尾遞迴
      def fac(n:Int,m:Int):Int={		//m用於記錄結果,不停的被覆蓋
      if(n==1) m
      else fac(n-1,m*n)
}

結果:
scala> fac(5,1)
res4: Int = 120