1. 程式人生 > >Scala學習筆記1

Scala學習筆記1

      本文件針對scala 2.10.x,由於scala目前發展迅速,因此可能會和其他版本的不同。

===概述

      scala是一門以java虛擬機器(JVM)為目標執行環境並將面向物件函數語言程式設計的最佳特性結合在一起的靜態型別程式語言。

      scala是純粹的面向物件的語言。java雖然是面向物件的語言,但是它不是純粹的,因為java的基本資料型別不是類,並且在java中還有靜態成員變數和靜態方法。相反,scala是純粹面向物件的,每個值都是物件,每個操作都是方法呼叫。

      scala也是一個成熟的函式式語言。函數語言程式設計有兩個指導思想:①函式是頭等值,也就是說函式也是值,並且和其他型別(如整數、字串等)處於同一地位,函式可以被當作引數傳遞,也可以被當作返回值返回,還可以在函式中定義函式等等;②程式的操作應該把輸入值對映為輸出值而不是就地修改,也就是說函式呼叫不應產生副作用,雖然函數語言程式設計語言鼓勵使用“無副作用”的方法,但是scala並不強制你必須這麼做。scala允許你使用指令式的程式設計風格,但是隨著你對scala的深入瞭解,你可能會更傾向於一種更為函式式的程式設計風格。向函數語言程式設計轉變,你就應該儘量去使用val、不可變物件、無副作用方法,而不是var、可變物件、有副作用方法。要明白的是,從指令式程式設計向函數語言程式設計的轉變會很困難,因此你要做好充分的準備,並不斷的努力。

      scala運行於JVM之上,並且它可以訪問任何的java類庫並且與java框架進行互操作,scala也大量重用了java型別和類庫。

第一個scala程式:

object ScalaTest {

         defmain(args: Array[String]) {

                   println("helloscala.")

         }

}

===scala直譯器

      安裝好scala並配置好PATH環境變數之後,就可以在終端中輸入scala命令開啟scala直譯器。在其中,你可以像使用shell一樣,使用TAB補全、Ctrl+r搜尋、上下方向鍵切換歷史命令等等。退出scala直譯器,可以使用命令:“:q”或者“:quit”。

      由於直譯器是輸入一句執行一句,因此也常稱為REPL。REPL一次只能看到一行程式碼,因此如果你要在其中貼上程式碼段的話,可能會出現問題,這時你可以使用貼上模式,鍵入如下語句:

                :paste

      然後把程式碼貼上進去,再按下Ctrl+d,這樣REPL就會把程式碼段當作一個整體來分析。

===scala作為指令碼執行

      scala程式碼也可以作為指令碼執行,只要你設定好程式碼檔案的shell前導詞(preamble),並將程式碼檔案設定為可執行。如下:

                #!/usr/bin/env scala

                println("這是scala指令碼")

      設定程式碼檔案為可執行,即可執行之啦。

      scala指令碼的命令列引數儲存在名為args的陣列中,你可以使用args獲取命令列輸入的程式引數。

===scala編譯執行

      scala編譯器scalac會將scala程式碼編譯為jvm可以執行的位元組碼,然後就可以在jvm上執行了。假設有一個Hello.scala 檔案,我們就可以使用 scalac Hello.scala 編譯,然後使用 scala Hello 執行。當然也可以使用java工具來執行,但需要在classpath裡指定scala-library.jar。對於classpath,在Unix家族的系統上,類路徑的各個專案由冒號“:”分隔,在MS Windows系統上,它們由分號“;”分隔。例如,在linux上你可以輸入這樣的命令來執行(注意classpath最後加一個“.”):

      java -classpath/usr/local/scala-2.10.4/lib/scala-library.jar:. Hello

===scala IDE開發環境

      你可以使用 eclipse 或者 intellij idea 作為scala的IDE開發環境,但都需要安裝scala外掛才行。下面分別介紹這兩種方式:

eclipse開發環境配置

      scala ide foreclipse(下載地址:http://scala-ide.org)中集成了scala外掛,你可以直接使用它進行開發,不過它包含的可能不是我們想要的scala版本,因此,還是在該網站上下載對應的scala外掛,插在eclipse上,這樣更好啊。

我們先安裝eclipse juno,然後下載eclipsejuno以及scala 2.10.4對應的scala sdk外掛升級包:update-site.zip。將外掛解壓縮,將featuresplugins目錄下的所有東東都複製到eclipse中的對應目錄中,重啟eclipse即可。然後就可以新建scalaproject了。

intellijidea開發環境配置

      我們先安裝好intellij idea,然後安裝scala外掛,自動安裝外掛有時會非常慢,尤其是在china。我們還是手動配置外掛吧。請注意外掛的版本,必須與當前idea版本相容。手動配置外掛方法如下:

      (1)進入 setting > plugins > browse repositorits 搜尋你要下載的外掛名稱,右側可以找到下載地址。

      (2)解壓外掛壓縮包,把外掛的全部檔案都複製到IntelliJ IDEA安裝程式的plugins資料夾中,注意外掛最好以一個單獨的資料夾放在plugins目錄下。

      (3)一般重啟intellij idea就會自動載入外掛,進入 setting > plugins 看看有木有。如果不自動載入的話,進入setting > plugins > install plugin from disk,找到剛才複製的外掛位置,再然後就好了。

接下來就可以新建scala project,新建時我選擇的是“Scala”(不是sbt,因為我這選擇sbt之後,等半天sbt都不會配置好,鬱悶啊)。

相關姿勢

      什麼是SBTSBT= (not so) Simple BuildTool,是scala的構建工具,與java的maven地位相同。其設計宗旨是讓簡單的專案可以簡單的配置,而複雜的專案可以複雜的配置。

===scala特點

      在scala中,語句之後的“;”是可選的,這根據你的喜好。當有多個語句在同一行時,必須加上分號,但不建議把多個語句放在一行。

      在scala中,建議使用2個空格作為程式碼縮排,不過我咋喜歡一個tab呢⊙﹏⊙!

      在scala中,符號“_”相當於java中的萬用字元“*”。

      scala類似於c++、java,索引也是從0開始,但元組是個例外,它從1開始。

===資料型別

      scala有7種數值型別:ByteCharShortIntLongFloatDouble,以及2種非數值型別:BooleanUnit(只有一個值“()”,相當於java和c++中的void,即空值)。這些型別都是抽象的final類(不能使用new新建,也不能被繼承),在scala包中定義,是對java基本資料型別的包裝,因此與java基本資料型別有相同的長度。同時,scala還提供了RichInt、RichChar等等,它們分別提供Int、Char等所不具備的便捷方法。

      另外,scala沿用了java.lang包中的String。在scala中,常量也稱作字面量,字串字面量由雙引號包含的字元組成,同時scala提供了另一種定義字串常量的語法——原始字串,它以三個雙引號作為開始和結束,字串內部可以包含無論何種任意字元。

      在scala中,我們使用方法,而不是強制型別轉換,來做數值型別之間的轉換,如99.44.toInt、97.toChar。另外也可以參見顯式型別轉換和隱式轉換。

===變數

      scala有兩種變數:valvar。val如同java中的final變數,var如同java中的非final變數。由於scala是完全面向物件的,因此valvar只是聲明瞭物件的引用是不可變的還是可變的,並不能說明引用指向的物件的可變性。宣告變數的同時需要初始化之,否則該變數就是抽象的。如果不指定變數的型別,編譯器會從初始化它的表示式中推斷出其型別。當然你也可以在必要的時候指定其型別,但注意,在scala中變數或函式的型別總是寫在變數或函式的名稱的後邊。示例如下:

            val answer = “yes”

            val answer, message: String =“yes”

===識別符號

      scala識別符號有四種形式:字母數字識別符號操作符識別符號混合識別符號字面量識別符號

      字母數字識別符號:跟其他語言類似,由字母、數字和下劃線組成,但需注意“$”字元被保留作為scala編譯器產生的識別符號之用,你不要隨意使用它啊。

      操作符識別符號:由一個或多個操作符字元組成。scala編譯器將在內部“粉碎”操作符識別符號以轉換成合法的內嵌“$”的java識別符號。若你想從java程式碼中訪問這個識別符號,就應該使用這種內部表示方式。

      混合識別符號:由字母數字以及後面跟著的下劃線和一個操作符識別符號組成。如unary_+定義了一個字首操作符“+”。

      字面量識別符號:是用反引號`…`包含的任意字串,scala將把被包含的字串作為識別符號,即使被包含字串是scala的關鍵字。例如:你可以使用Thread.`yield`()來訪問java中的方法,即使yield是scala的關鍵字。

===操作符

      scala的操作符和你在java和C++中的預期效果是一樣的,但注意scala並不提供++、--操作符。不過,scala中的操作符實際上都是方法,任何方法都可以當作操作符使用,如 a + b 相當於 a.+(b)。

      需要注意的是:對於不可變物件(注:物件的不可變並不是說它的引用變數是val),並不真正支援類似於“+=”這樣以“=”結尾的操作符(即方法),不過scala還是提供了一些語法糖,用以解釋以“=”結尾的操作符用於不可變物件的情況。假設a是不可變物件的引用,那麼在scalaa += b將被解釋為a = a + b,這時就相當於新建一個不可變物件重新賦值給引用a,前提是引用變數a要宣告為var的,因為val變數定義之後是不可變的。

更多資訊參見函式(方法)部分。