最近開始系統性的學習scala。其實之前使用過scala的,比如我在用Gatling這款性能測試工具的時候就接觸到了scala了。Gatling本身就是用Scala寫的,而且Gatling的性能測試配置文件本身就是一個scala類,可以隨意使用scala甚至是Java提供的各種類庫。當時覺得用Gatling特別舒服的原因就在于配置文件強大的表現力。而這種表現力就是由Scala語言提供的。
言歸正傳,學習Scala還是從最簡單的Hello world開始。在Scala官網中顯著的標題就是:
Object-Oriented Meets Functional
Have the best of both worlds. Construct elegant class hierarchies for maximum code reuse and extensibility, implement their behavior using higher-order functions. Or anything in-between.
從中可以看出Scala結合了面向對象及函數式編程這兩種編程范式。在本文中我將會拿Java語言和其比較,看看到底Scala強在那里。
使用Java語言實現一個Hello World的代碼如下:
1 2 3 4 5 |
|
以下是Scala的實現:
1 2 3 4 5 |
|
好吧,如果標點符號不算代碼行,Java版本和Scala版本的實現的代碼行數是一致的。貌似Scala并沒有減少什么。唯一減少的就在于println不用指定類名,以及對main方法不用聲明為static。
在這里對Scala實現與Java實現的幾個不同之處做個介紹。
第一是Scala對HelloWorld的修飾符使用的是object。其實Scala中也有class關鍵字,那么object關鍵字和class關鍵字有什么區別那?簡單來說object關鍵字定義了一個匿名類,并且創建了該匿名類的單個實例(采用單例模式),該實例名為HelloWorld。所以object中定義的方法自動都是static的。我覺得object關鍵字存在的價值之一就是建立起了面向對象和函數式的橋梁。因為在面向對象的系統中,所有方法都必須存在于類中,而函數式編程中沒有類的概念,使用函數無需new類的實例,所以object中的方法都是靜態方法,可以直接被調用。進一步解讀請到這里。
第二是Scala中對變量的類型的定義方式是變量名在前,類型在后,中間用冒號相隔。原因之一是代碼更可讀。因為我們更關心變量名,而類型其次,尤其是你擁有一個超級長的類型的情況下(比如 HashMap<Shape, Pair<String, String>>);原因之二據說是這樣的方式在實現Scala類型時技術上要簡單些。進一步解讀請到這里。
第三是main函數的返回值是Unit,而不是Java中的Void。為什么是這樣那?我想是因為Scala為了實現自己的類型系統,對于無顯式返回值的函數直接使用Void是不合適的。在Scala.Unit文檔中是這樣定義Unit的:
Unit is a subtype of scala.AnyVal. There is only one value of type Unit, (), and it is not represented by any object in the underlying runtime system. A method with return type Unit is analogous to a Java method which is declared void.
- 第四是Scala中表達式最后的分號是可選的。原因就是為了契合函數式編程的哲學,即一切盡可能的簡單。不寫分號程序員一天可以多敲一些代碼出來。
好吧,其實在Scala中Hello World還有一種寫法。
1 2 3 |
|
代碼從三行減少到了兩行,Scala終于勝出了。那么App是個什么鬼?App是一個trait。trait又是什么鬼?trait是Scala中的一個特殊類型,它與Java中的interface很相似,但比interface強大。HelloWordV2添加了對App的擴展后,就自動成為了一個可以運行的程序,由于App中定義了main方法,所以HelloWorldV2中就無需再定義了,牛逼的地方在于HelloWorldV2的body中的代碼都會作為main方法中的代碼被執行。以下是App源碼中對main方法的定義:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
看來App在實現main方法時還設置了一個計時器,通過scala.time這個屬性來開關。所以沒事翻翻源碼還是挺好玩的。
不知有沒注意到其實main方法是有個叫args的參數的,那么新版HelloWorld中如何使用該參數那?直接使用它就行。
1 2 3 |
|
ok,Scala版的Hello World就到這里吧。
文章列表