Scala與Java具有許多相似之處,但又有許多不同。這里主要從一個(gè)Java開發(fā)人員的角度,總結(jié)在使用Scala的過程中所面臨的一些思維轉(zhuǎn)變。這里只是總結(jié)了部分兩種語言在開發(fā)過程中的不同,以后會(huì)陸續(xù)更新一些切換后在開發(fā)過程中值得注意的地方。下面列舉了部分,但令人印象深刻的Scala語言的不同之處,具體的代碼示例及詳細(xì)闡述見下文。
- Scala中可直接調(diào)用Java代碼,與Java無縫連接;
- 語句可以不用“;”結(jié)束,且推薦不適用“;”;
- 變量聲明時(shí)以var或val開頭,可不必指定變量類型,編譯器可推斷變量類型;
- 函數(shù)可以不定義返回值類型(特殊情況除外);
- 函數(shù)返回值可不用return返回;
- 無參函數(shù)定義及調(diào)用時(shí),函數(shù)名后可不跟括號(hào);
- 數(shù)組訪問下標(biāo)使用括號(hào),而不用中括號(hào);
- 元組使用“._n”的方式訪問元素,n從1開始;
- ……。
指定Main函數(shù)
在Java中運(yùn)行程序,只要指定入口的Main函數(shù)即可。一個(gè)工程中可以有多個(gè)Main函數(shù),每個(gè)類內(nèi)都可以定義Main函數(shù)。但是與Java不同的是,Scala工程中,只有定義在object中的Main函數(shù)才能作為程序入口,下圖中定義在class中的Main函數(shù)是無法作為程序入口的。
要想程序能夠執(zhí)行,需要如下圖所示,將Main函數(shù)定義在object中。在Scala中,class同Java中的類一樣,但是Scala中沒有static類型的類,與此同時(shí),Scala中提供了一種object的定義方式,通過這種方式定義的“類”類似于Java中的static類,使用時(shí)不需要new相應(yīng)的對(duì)象,直接使用外面能訪問的變量和函數(shù)。object中定義的方法也類似于static方法,直接通過object名訪問。

變量和字段聲明
與Java中定義變量不同,在Scala中變量是通過“var|val 變量名 [: 類型] = 值”這種方式聲明和定義的。在聲明字段的時(shí)候,可以使用編譯器自動(dòng)推斷類型,即不用寫“ : 類型”,比如
var i : Int = 2;
或直接
var i = 2;
var和val的區(qū)別是:var聲明的變量的值之后還可以改變,而val聲明的變量只能在聲明時(shí)賦值,之后不能改變?cè)撟兞康闹担愃浦蛔x變量,但不是常量)。Scala的函數(shù)式編程更推薦使用val。
類的定義及不同
如下圖所示,在Scala中也是通過class關(guān)鍵字定義類,看起來與Java中類似。在Scala類中默認(rèn)的訪問符是public,如果不明確的寫明private或其他訪問符,則類里的成員默認(rèn)都是可以公開訪問的。
但是Scala在構(gòu)造函數(shù)方面與Java存在許多不同,Scala類中包括主構(gòu)造器和附屬構(gòu)造器。Scala中類的主構(gòu)造器:主構(gòu)造器直接跟在類名后面,主構(gòu)造器中的參數(shù)會(huì)被編譯成類的字段;主構(gòu)造器執(zhí)行的時(shí)候會(huì)執(zhí)行類中的所有不包含在方法體中的語句;如果在主構(gòu)造器函數(shù)的參數(shù)中沒有用val或者var去聲明變量,那此時(shí)的變量是private[this]級(jí)別的,只能夠被類內(nèi)部訪問。Person類的主構(gòu)造器如下圖所示,主構(gòu)造器中的參數(shù)name和age會(huì)被作為Person類的兩個(gè)成員變量,未被包含在任何方法內(nèi)部的打印語句會(huì)作為主構(gòu)造器中的語句被執(zhí)行。
由于上圖中定義的age沒有使用val或var修飾,所以會(huì)被作為private類型的成員變量使用,這類變量只能在類內(nèi)部訪問。因此如下圖所示,name能在類外部訪問,而age不能被外部訪問。
以上是主構(gòu)造器的情況,Scala中還包括一類附屬構(gòu)造器,即除主構(gòu)造器外的其他構(gòu)造函數(shù),附屬構(gòu)造器有以下特點(diǎn):附屬構(gòu)造器是用this來聲明的;附屬構(gòu)造器中必須調(diào)用主構(gòu)造或者其它附屬構(gòu)造器。如下圖所示為附屬構(gòu)造器的例子。

特別的函數(shù)定義
Scala中的函數(shù)定義與Java中有所區(qū)別,總體來說如下這種方式,返回值類型在參數(shù)列表后面通過“: 類型”這種方式指定,然后通過“=”承接函數(shù)體。對(duì)于無返回值類型的,類型可以寫“Unit”(類似Java中的void),對(duì)于函數(shù)體簡(jiǎn)單的,“=”后面可直接接語句,不用“{}”。
與Java不同的是,語句塊或函數(shù)返回值可以不用顯示的通過“return”語句返回,一般塊的最后一個(gè)表達(dá)式的值就是函數(shù)的返回值。因此上述函數(shù)可修改為下面的形式。
同變量聲明不需要顯示指定類型相同(變量可以推斷變量類型),所以函數(shù)也可以推斷返回類型,因此可以簡(jiǎn)寫成如下所示:
然而,需要注意的是:如果函數(shù)使用return返回,那么必須明確指定函數(shù)的返回類型;此外如果是遞歸函數(shù),也需要指定返回類型。下圖所示為通過“return”返回的函數(shù),函數(shù)定義時(shí)沒有指定返回類型,編譯器報(bào)錯(cuò)。
對(duì)于函數(shù)參數(shù)列表為空的,定義時(shí)函數(shù)名后可以不跟“()”,使用時(shí)也可以不跟“()”,如下圖所示:

數(shù)組及元組的使用
兩種數(shù)組定義如下圖所示,與Java不同的是需要用到Array關(guān)鍵字。同Java中一樣,數(shù)組長(zhǎng)度不可變,數(shù)組元素可變。
Scala中數(shù)組通過下標(biāo)對(duì)元素訪問的方式如下圖所示,主要通過2種方式,第一種是通過“arr(i)”這種方式,與Java中不同,Java中主要通過“arr[i]”這種方式訪問。這是因?yàn)樵赟cala中,任何操作符都是函數(shù)調(diào)用的方式進(jìn)行的。此外還提供了“arr.apply(i)”這種訪問方式。
數(shù)組賦值和修改可通過下面兩種方式進(jìn)行,第一種適合代碼顯示賦值和修改,第二種適合程序運(yùn)行階段根據(jù)條件對(duì)特定元素賦值和修改。
對(duì)于數(shù)組的遍歷可通過以下2種方式。其中第一種注意for循環(huán)的to也會(huì)取到;第二種遍歷方式是通過foreach的方式傳遞匿名函數(shù),如果數(shù)組元素需要指定類型,需要用“(item : String)”括號(hào)括起來,如果處理代碼較復(fù)雜,可用“{}”語句塊表示。
Scala中元組的定義和元素訪問如下所示,定義時(shí)直接使用“()”將不同的類型的若干變量或字面值包圍起來即可。值得注意的是,對(duì)于元組元素通過“._n”的方式進(jìn)行訪問,且n從1開始計(jì)數(shù)。

參考
Scala學(xué)習(xí)筆記系列
Scala基礎(chǔ)之函數(shù)
Scala的循環(huán)和數(shù)組
面向 Java 開發(fā)人員的 Scala 指南系列
|