Scala Tutorial(2)準備開發環境、Scala 中的四則運算 by brianhsu | CodeData
top

Scala Tutorial(2)準備開發環境、Scala 中的四則運算

分享:

Scala Tutorial(1)靜態型別也可以很方便 << 前情

安裝 Java 與 Scala

由於 Scala 不論是編譯與執行,均是運行在 Java 虛擬機器上,因此在安裝 Scala 之前,必須先安裝 Java 執行環境,才能讓 Scala 正確執行。

目前執行 Scala 的需求是 Java 1.6 以上,但使用最 1.7 或 1.8 版本的 Java 也可以正常執行,讀者可以直接到 Java 網站下載最新的 Java 執行環境。

以 Windows 為例,進入 Java 官方網站後,點擊「免費 Java 下載」的按鈕,就可以下載 Java 的安裝程式,安裝的過程相當簡單,只需要在安裝程式執行後點選「安裝」按鈕即可。

Java 安裝畫面

在 Java 安裝完成之後,我們還需要將 Java 的可執行檔路徑加到 Windows 系統的 Path 變數中,若在安裝過程中沒有更改 Java 的安裝路徑,則其預設路徑依照其為 32 位元或 64 位元版本,會是以下的其中一個:

  • C:\Program Files (x86)\Java\jre7\bin
  • C:\Program Files\Java\jre7\bin

若不確定 Java 的安裝路徑,可以將以上兩個路徑複製到檔案管理員中,正確的路徑應該可以看到 java.exe 執行檔,與其他各種 .dll 檔案。

確認過 Java 執行檔路徑後,可以依照下述方式將其加入 Windows 系統的 Path 變數:

  1. 在「我的電腦」上按滑鼠右鍵並點選「內容」
  2. 點後左邊的「進階系統設定」後再點選「進階」標籤
  3. 點選視窗下方的「環境變數」,此時會跳出新的「環境變數」視窗
  4. 在下半部份的「系統變數」中找到 Path 變數,並將 Java 的執行路徑填入,並以 ; 做為與上個路徑的分格符號

Java 執行路徑設定

安裝完 Java 之後,接下來進入 Scala 的下載頁面,並點選第一個 Scala 2.11.1 的 Donwload 按鈕,會開始下載 Scala 的安裝程式,執行後只需要照著螢幕上的指示並安裝即可。[註1]

Scala 安裝程式

同樣的,在安裝完後我們必須先確定 Scala 的執行檔必需在 Windows 系統的 Path 中:

Scala 執行路徑設定

確定 Scala 的路徑被加入 Path 變數中後,我們可以開啟 Windows 的命令提示字元程式,並輸入 scala 指令進入 Scala 的 REPL 介面,若看到出現 scala> 的字樣,就代表了我們已經成功安裝 Scala。

Scala 的 REPL 介面

給 Scala 使用的 IDE

雖然在這份教程中不會使用到 IDE,但在這裡列出目前已經有的 Scala IDE 供讀者參考,這些 IDE 多數是建構在現有的其他 IDE 程式上的插件,因此若讀者已經有慣用的 IDE,亦可以嚐試使用這些 IDE 來撰寫 Scala 程式。

ScalaIDE
ScalaIDE 是給 Eclipse 使用的 Scala 插件,支援程式碼補齊、彩色語法標示與錯誤標示等等。
IntelliJ IDEA Scala Plugin
不論是付費的 Ultimate Edition 版本或是開源的 Community Edition 版本,均可使用此插件,同樣也支援程式碼補齊與錯誤標示等常見的 IDE 功能。

萬物皆是物件

進入 Scala 的 REPL 系統後,我們可以看到 scala> 的提示符號,這代表 Scala REPL 告知我們他已經準備好接受我們的指令。

首先我們先執行第一道運算式,在 Scala REPL 中輸入 1 + 1 並按下 Enter 鍵,Scala REPL 會出現如下的反應:

scala> 1 + 1
res0: Int = 2

在這裡,Scala REPL 會替每一個運算式執行後的結果賦與一個暫時的變數名稱,我們可以在後續的運算式中使用這個名稱來存取這個運算式的返回值,而不需要重新輸入同樣的運算式。在這個例子中該變數的名稱為 res0,名稱後的 : Int 代表這個運算式返回的結果的類別為 Int,等號後的 2 則告我們返回的值是 2。

與 Java 不同的是,雖然在這裡 + 號看起來像是運算元符號,但由於在 Scala 中萬物皆是物件,而且在 Scala 中函式或方法的名稱可以是特殊字元,所以實際上 + 符號是被定義在 Int 類別中的方法 (method)。

由於 + 號只是定義在 Int 上的方法,所以我們可以用和 Java 同樣的語法來呼叫這個方法:

scala> (1).+(1)
res1: Int = 2

在這裡,Scala 只是單純的把 A + B 代換成 A.+(B) 而已,依據相同的規則,在 Scala 中我們可以使用運算元的方式來呼叫任何只有一個參數的方法。

舉例來說,我們已經知道 Java 的字串物件中有一個 charAt 方法,可以告知我們該字串在某個位置上的字元是什麼,所以我們可以使用傳統的 . 符號來呼叫這個方法,亦或者使用運算元的方式來呼叫這個方法,在 Scala 裡兩者是相同的。

scala> "Hello World".charAt(3)
res2: Char = l

scala> "Hello World" charAt 3
res3: Char = l

同樣的,由於在 Scala 中 Int 也是物件,所以也定義了其他的方法,我們可以輸入 1. 之後按一下鍵盤的 TAB 鍵,Scala REPL 會告訴我們可以使用的方法:

scala> 1.
%              &              *              +              -              /              
>              >=             >>             >>>            ^              asInstanceOf   
isInstanceOf   toByte         toChar         toDouble       toFloat        toInt          
toLong         toShort        toString       unary_+        unary_-        unary_~        
|

若要更進一步察看每個方法可以傳入什麼樣的參數,我們可以輸入該方法名稱後再按兩下 TAB 鍵,就會出現該方法的函式宣告,告知使用者其接受的參數型別與返回值的型別。

scala> 1.+
  def +(x: Byte): Int        def +(x: Char): Int        
  def +(x: Double): Double   def +(x: Float): Float     def +(x: Int): Int         
  def +(x: Long): Long       def +(x: Short): Int       def +(x: String): String

在這裡我們可以看到,Int 上的加號除了遇到字串會返回另一個字串(符合 Java 中 + 號可以用來建立字串的習慣),其他的情況下都是返回數值型態的值。

這個技巧非常適合用在實驗缺少文件的函式庫上,我們可以使用 Scala REPL 來出函式接受的參數型別與測試其執行的結果而不用撰寫完整的程式碼。

Scala 中運算元的優先權

讀者可能會想,如果在 Scala 中所有的運算元都只是函式呼叫,那麼像是四則運算裡先乘除後加減的優先權概念會是如何呢?我們可以先在 Scala REPL 中輸入一個含有不同優先權的四則運算式:

scala> 1 + 3 * 5
res1: Int = 16

在這個例子中,我們可以看到確實 3 * 5 這個運算式的優先權是較高的,因此 Scala 先得出了 15 這個返回值,這才將其做為參數傳遞給 + 這個函式上。

但如果 Scala 中所有的運算元都是函式呼叫的話,優先權要如何決定呢?事實上在 Scala 的規格書當中寫道,當我們使用 infix 的方式來呼叫函式時,函式的優先權是依照函式開頭的第一個字元所決定的,依照優先權從低到高如下表所示[註二]:

(所有字母)
|
^
&
< >
= !
:
+ -
* / %
(所有特殊字元)

在這個表中,我們可以看到以 * 號開頭的函式的優先權比以 + 號開頭的來得高,所以在上述的 1 + 3 * 5 運算式中 3 * 5 會先被執行,這才執行 1 + 15 這個運算式。

相同的,我們知道在 Java 的 String 類別中有 contains 這個方法,由於這個函式是由字母開頭,因此做為運算元時其優先權是表中最低的,所以若我們直接輸入下列的運算式,則 Scala 會告知錯誤。

scala> "Hello" contains 'A' && "World" contains 'D'
<console>:8: error: value && is not a member of Char
              "Hello" contains 'A' && "World" contains 'D'

因為以 Scala 對於運算元的優先順序,這個運算式實際上是

(("Hello" contains ('A' && "World")) contains 'D')

也就是說,&& 符號會先被執行,但由於 && 這個方法並沒有被定義在 Char 類別中,所以 Scala REPL 告知我們這個錯誤:「&& 不是 Char 類別的成員」。

若要讓上面這個運算式可以被正確的執行,我們可以和 Java 一樣用括號來調整運算式的優先權,使其可以正確的執行。

scala> ("Hello" contains 'A') && ("World" contains 'D')
res4: Boolean = false

最後順帶一提,在該運算元是左結合或右結合方面,Scala 是依靠該函式的最後一個字元所決定的,任何以 : 結尾的方法在當做運算元使用時是右結合,以其他字元結尾的方法則一律是左結合。

小結

在這一篇中,我們看到了如何安裝並準備 Scala 的開發環境,如何使用 Scala REPL,還有在 Scala 中運算元其實只是定義在物件上的方法,以及在所有運算元都只不過是方法時,Scala 是如何決定運算元的優先權與左結合或右結合等。

有了這些基礎的認知,下一次開始我們將進入到 Scala 中變數與函式的宣告,並且看 Scala 是如何巧妙地將物件導向與函數式編程給融合在一起。


[註1] 若您的作業系是 Linux 或 MacOS,則只會下載一個壓縮檔而不是安裝程式,只需要解壓縮並將其中的 bin/ 目錄加入系統的 PATH 變數中即可。

[註二] 此表摘自 Scala 規格書 2.9 版(2014 年 3 月),但實際上有誤,目前 Scala 編譯器的實作上以 = 號開頭運算元的優先權低於以 < 或 > 開頭的運算元。

後續 >> Scala Tutorial(3)變數與函式

分享:
按讚!加入 CodeData Facebook 粉絲群

相關文章

留言

留言請先。還沒帳號註冊也可以使用FacebookGoogle+登錄留言

Aames Jiang09/02

文末的[後續 >> Scala Tutorial(3)變數與函式] 的 link 是錯的喔

熱門論壇文章

熱門技術文章