1. 程式人生 > 實用技巧 >寒假學習日報(十)

寒假學習日報(十)

  昨天晚上又熬夜了,今天整個人狀態都很差。下午找了一下假期需要閱讀的書籍,補上了一篇讀書筆記。

  程式設計方面簡單看了一下scala,因為要開始spark的學習了,為了能更好地掌握spark,我決定先接觸一下scala,因為spark是用scala編寫的。今天的日報僅僅對scala做一個介紹,因為並沒有敲多少程式碼,大部分時間都用去看書和學習視訊了。

  Scala主要特點是支援函數語言程式設計,它可以巢狀呼叫java程式碼,可以被JVM執行。Scala中可以使用val,var,def三種關鍵字來命名,val是immutable型別,只能在初始化的時候賦值一次,var表示mutable型別,可以被賦值多次,def關鍵字宣告是function value,同樣是immutable型別,只有在使用時才會分配變數。變數定義如下(插入程式碼選項裡沒有scala,因此使用java格式進行插入

):

val a = 1
var b = 2
def c = 3

  函式定義舉例:

//int型引數的+1操作,無返回值。
def f(x: Int) = {x+1};
def f(x: Int) = x+1
def f(x: Int) = (x+1)

//不帶引數,沒有返回值的函式,通過o呼叫,直接輸出
def o{println("Hello Scala")}

//帶引數,型別為Unit,返回型別為Unit
def add(x: Unit):Unit={
println(x)
x
}

//匿名函式
(x: Int)=>x+1    //等價於{def f(x: Int) = x + 1; f _}

  高階函式,函式引數可以為函式:

// 引數func為函式型別的變數,GaoJie為高階函式,函式會把一個List中的元素按照func來做對映
def GaoJie(arr: List[Int], func: (Int) => Int): List[Int] = {
  arr.map(func)
}
Test(List(1,2,3), (x: Int) => x*x)

  Scala支援函數語言程式設計,其中使用了非常多的遞迴,以階乘程式碼舉例:

def ff(n: Int): Int =
  if (n == 0) 1 else n * ff(n - 1)
/* 
函式的呼叫方式如下
ff(3)
if(3 == 0)1 else 3*ff(3 - 1)
3*ff(2)
3*(2*ff(1))
3*(2*(1*ff(0)))
3*(2*(1*(1*1)))
6
*/

  除了上述實現過程,還有另一種方式:尾遞迴

def ff(n: Int): Int = {
  @tailrec
  def ta(x: Int, res: Int): Int =
    if (x == 0) res
    else ta(x - 1 , res * x) 
    ta(n, 1)
}
// ff(3)結果是6
/*
函式的呼叫方式如下
ff(3)
ta(3,1)
if(3==0) 1 else ta(2,3*1)
if(2==0) 3 else ta(1,3*2)
if(1==0) 6 else ta(0,3*2*1)
if(0==0) 6 else ta(...)
return 6
*/

  尾遞迴過程中不需要儲存之前呼叫的堆疊,因為結果(res)作為一個引數傳遞了下去,Scala編譯器會對此做一個自動優化,避免過多的堆疊呼叫開銷。

  柯里化(Currying):函式返回值依然為函式

def cur(x:Int): (Int)=>Int = {
  def squ(y:Int): Int = {
    y*y
  }
  x + squ(_)
}
// cur(1)(2)=5
// 等價於下面的實現方式
def cur(x:Int, y:Int): Int = {
    x + y*y
}

  以上是今天的全部學習內容。