scala 學習筆記(scala for the impatient)

    好久沒有寫東西了,忽然想寫點什麼,還感受不怎麼適應,呵呵,隨便寫點吧,話很少說,進入主題吧。 java

    scala 融合了面相對編程和麪向對象編程的思想,如今java8出世了,其中的lambda表達式和scala的語法很類似,估計面向函數編程會成爲一種趨勢。 編程

    經過這段時間的學習,最大的感受就是scala語法相對於java來講要簡潔得多,面向函數編程確實使人眼前一亮,下面記錄下今天所學習知識的筆記。 數組

    (1)、表達式:scala的條件表達式即if/else有值,能夠將此值賦給變量,這是在java不能實現的,如val s = if(x > 0) 1 else –1。若是else部分缺失了的話,如val s2 = if(x > 0) 1,若是x 不大於0的話,此時s2的值爲unit,寫做()。此時表達式至關於val s2  = if(x > 0) 1 else ()。 函數

     (2)、語句終止:在java中每個語句的是以分號結束的。而scala與javaScript和其餘腳本語言相似,行尾位置不須要分號。若是在單行寫下多個語句,就須要將它們以分號分開。如 if(n > 0){ r = r  *  n; n –= 1}。 學習

     (3)、塊表達式和賦值:在java中,塊語句包含於{}中的語句序列,每當須要在邏輯分支或循環中放置多個動做時,均可以使用塊語句。在scala中,{}包含一系列表達式,塊最後一個表達式的值就是塊的值。此特性對於那種對某個val須要分多步初始化時很是有用。如val distance = {val dx = x – x0; val dy = y – y0; sqrt(dx * dx + dy * dy)}。此時distance的值爲sqrt(dx * dx + dy * dy)。賦值動做自己是沒有值的,或者說值爲unit類型。unit至關於java中的void,所以在scala中不能以下這樣寫:x =y =1 google

     (4)、輸入和輸出:scala中從控制檯輸入信息,用readLine、readInt、readDouble等 url

     (5)、循環:scala和java擁有想通的while和do循環。如 while (n > 0) {r = r * n; n –= 1},scala沒有與java中循環對應的結構,scala中for語句: spa

for( i <- 1 to 10)&#160; s= s+1 ,此表達式中i無需聲明類型,該變量的類型是集合元素的類型。當遍歷字符串或者數組時,一般須要使用0到n-1的區間,此時能夠用until方法,for(i <- 0 until 「adsad」.length) sum += s(i);此處是爲了展現until的用法,此式例能夠用這種寫法替代: for( ch <- 「adsad」) sum += ch 。scala的for循環有很豐富的功能,能夠用 「變量<-表達式」提供多個生成器,用分號將它們隔開,如:for(i <- 1 to 4; j <-1 to 7) print(i * j + 「 」),而且每一個生成器能夠帶一個守衛(以if開頭的Boolean表達式),如:for(i <- 1 to 3;j <- 1 to 7 if i != j ) print(i * j "+ 「 」),第二個生成器帶了 「if i != j」守衛。除了守衛以外咱們還可使用任意多的定義,如:for(i <- 1 to 3;x = i + 1;j <- x to 7 if i != j ) print(i * j "+ 「 」)。scala的for循環還能夠以yield開始構造一個新的集合,每次迭代生成新集合中的一個值,如:for(i <- 1 to 10) yield i + 1 ,此時生成vector(2,3,4,5, … ,11),這類循環叫作for推導式,for推導式生成的集合和它的第一個生成器是兼容的。 scala

    (6)、函數:scala除了方法還支持函數,方法對對象進行操做,函數不是,在java中咱們只能用靜態方法來模擬。函數定義:def f1(x: Double) = if (x > 0) x else –x ,只要函數不是遞歸的,就不須要指定返回類型,scala編譯器能夠經過」=」號右側的表達式類型推斷出返回類型。對於遞歸函數,咱們就必須指定返回類型,如:def f(n: Int): Int = if(n < 0) 1 else f(n - 1),若是沒有返回類型,scala編譯器沒法校驗 f(n - 1)的類型是Int。 code

    (7)、默認參數和帶名參數: 默認參數,def f(str: String, left: String = 「xx」,right: String = 「yy」) = left + str + right;帶名參數:調用函數的時候,若是在提供參數值的時候指定了參數名,則參數順序並不須要跟參數列表的順序一致,如:def(left=」ss」,right=」xx」,str = 「abccd」)

    (8)、變長參數:顧名思義就是你可使用任意多的參數來調用此函數,如:def sum(args: Int*) = {var r = 0; for(arg <- args) r += arg; r},調用此函數:val s =sum(2,34,23,12,23) 。函數獲得一個類型爲Seq的參數,若是想將一個有值的序列當作參數序列處理,你得告訴編譯器你但願這個參數被當作參數序列處理,追加「:_*」,如:val s = sum(1 to 34:_*) 

    (9)、過程:若是函數體包含在{}中但沒有前面的=號,那麼返回類型就是Unit,這種函數就稱做過程。咱們調用過程是爲了它的反作用,好比把消息輸出到控制檯等等。

     (10)、懶值:當val被聲明爲懶值(lazy)時,它的初始化將被延遲,直到咱們首次對它取值。如:lazy val str = scala.io.Source.fromFile("c/user/abc").mkString。若是程序不訪問str,則文件不會被打開。懶值對於開銷較大的初始化語言頗有用。懶值處於val和def的中間狀態。

    (11)、異常:scala的異常工做機制和java基本上差很少,與java所不一樣的是scala沒有「受檢」異常,throw表達式有特殊類型Nothing。在if/else中頗有用,若是一個分支的類型爲Nothing,那麼if/else表達式類型就是另外一個分支的類型。scala捕獲異常採用模式匹配的語法,如:

try{ 
    process(new URL("https://www.google.com") )
}
catch {
 case _: MalformedURLException => println("Bad URL:" + url )
 case ex: IOException => ex.PrintStackTrace()
}

若是你不須要使用捕獲的一場對象,可使用_來替代變量名。

相關文章
相關標籤/搜索