scala函數式編程(二) scala基礎語法介紹

上次咱們介紹了函數式編程的好處,並使用scala寫了一個小小的例子幫助你們理解,從這裏開始我將真正開始介紹scala編程的一些內容。java

這裏會先重點介紹scala的一些語法。固然,這裏是假設你有一些java或者python的基礎,畢竟大部分人不會將scala看成第一門學習編程的語言。python

不過這些語法知識記不住也不要緊,自己語法這種東西就應該在使用中被記住。這裏寫這篇的目的也只是梳理一遍,方便你們對語法有個初步的印象,後面能夠隨時查詢。編程

PS:所使用的版本是scala 2.11.8,那咱們開始吧json

一.scala兩種運行方式

首先,scala有兩種運行方式,分別是在交互式環境運行,以及經過腳本的方式運行。先運行一下吧,在scala安裝目錄下有一個bin文件夾,在這個文件夾雙擊scala.bat(Windows系統),就能夠啓動scala交互環境。固然,通常在安裝scala,都會將「scala目錄/bin」加入到系統的Path變量中,這個時候直接運行cmd,而後輸入scala就能夠了。併發

由於scala也是運行在jvm平臺上的,因此用腳本方式的話,相似於java那樣,須要先編譯再執行。可是通常咱們都會使用IDE來處理。經過我我的是更加喜歡idea的,只要下載免費的社區版就能夠知足平常開發需求。app

二.scala變量和類型

2.1 變量

首先,咱們先來用一個例子來看看具體語法。在交互式環境中輸出hello world。異步

//聲明一個字符串
scala> val str = "Hello world"
str: String = Hello world

//打印
scala> println(str)
Hello world

相信你們看一眼就能明白這兩行代碼是幹嗎的,那我就說一點看不出來的。jvm

scala聲明一個變量能夠用val和var。val意爲這個變量是不可變的,var意爲這個變量是可變的。ide

scala> val num = 1;  //聲明一個不可變的數值型變量
num: Int = 1

scala> num = 2  //由於不可變,因此要更改時,出錯了
<console>:12: error: reassignment to val
       num = 2
           ^

scala> var num_var = 1;  //聲明一個可變的數值型變量
num_var: Int = 1

scala> num_var = 2; //能夠改變
num_var: Int = 2

從功能上來講,相似於java的final關鍵字。並且scala語言傾向於讓你多使用val,而少用var。模塊化

爲何呢?

由於可以更方便得使用併發,在java的併發編程中,最喜歡的就是final的變量,由於它都是不變的,隨便怎麼用就怎麼用。而scala所支持的函數式編程,自然就適合異步和併發,因此作了這樣的處理,包括scala的集合類,默認也是不可變的類型,若是要使用可變的集合,須要手動指定。

2.2 scala數據類型

說完了變量,再來講說scala的數據類型。這裏直接上一張圖。

這張圖說明了scala的數據類型繼承關係,咱們先看最上面的Any類型,Any類型是全部數據類型的爸爸,在它裏面定義了equals,toString這些方法,相似於java的object。這一點和java仍是比較相似的。

而後接着往下看,Any又有兩個字類,左邊的AnyVal以及右邊的AnyRef。右邊的先無論,那個主要是集合那邊的知識,咱們只看左邊的。

AnyVal又被多個數據類型繼承,這些就是平常經常使用的一些數據類型了,能夠看到和Java相似,都是Int,Double,Long這些。對了,這些數據類型,Int,Double,Long什麼的,都是類,不像java,還有分int和Integer。

最後再來看看最下面的Nothing和Null吧,把這倆貨擱在一塊說是由於這幾個概念很是容易混淆,我本身要用的時候還得去查清楚了。

  • java的null(scala也能夠用,不過n是小寫):就是表明沒有任何東西,即空。通常新建一個對象,默認值就是這貨。
  • scala的Nothing:全部數據類型的子類,沒有具體的值能夠對應到這種類型,也就是說你無法爲Nothing類型賦值,包括null也不行。那可能有的小夥伴就會問了,那要這個玩意幹嗎呢?通常嘛,try catch的返回值就是這種類型,還有程序exit的時候也是返回它,大概就是在不須要返回值的時候,就返回這個意思意思。
  • scala的Null(注意大小寫):是全部集合類的子類,這種類型只能使用null來賦值,能夠說基本沒什麼卵用。只要知道有這麼個東西就行。

三.scala面向對象編程

是的,你沒看錯,雖然這裏是用scala來進行函數式編程,但scala也一樣提供了OOP的能力,後面有很大的機率也會說到,咱們就順帶着簡單介紹一下吧。

仍是和java中的概念相似,只不過名字稍稍有些變化。對應過來大概是這樣的:

  • java的interface -> scala的trait (其實trait更相似abstract class)
  • java的abstract class -> 同樣是abstract class
  • java的class -> scala的class和object(關於class和object的區別,會在後面說)

其中,雖說java的接口對應的是scala的trait,但trait這個東西其實和interface仍是有不少不同的,好比能夠定義變量,能夠直接定義方法內容等。固然,沒有構造器和沒法接收參數這個仍是不變滴。

trait Car {
  val brand: String
}

trait Shiny {
  val shineRefraction: Int
}
class BMW extends Car {
  val brand = "BMW"
}
//經過with關鍵字,一個類能夠擴展多個特質:

class BMW extends Car with Shiny {
  val brand = "BMW"
  val shineRefraction = 12
}

接下來重點說說class和object。

在scala中,是沒有static這個關鍵字的,那麼這樣一來,不少java的功能就都無法實現,好比靜態方法,或者是單例模式,或者是沒有main方法。這個時候,object就出現了。

每一個class均可以有一個同名的object,這個object被稱之爲伴生對象(companion class)。class和object能夠互相訪問對方的私有成員(public,private這些權限訪問和java是同樣的)。

class Json{
  
}
object Json {
  def toJsonObject(str:String):Unit = {
    
  }
  var a = 1
  def main(args:Array[String]):Unit = {
    val json = Json
    json.toJsonObject("......")  //不須要new對象,直接使用toJsonObject方法。

  }
}

得益於object,咱們能夠像調用java靜態方法同樣地寫scala代碼,而這一切,都要歸功於object。

由於!object裏面的變量,或是方法,都是static的,這裏說的static是方便有java基礎的童鞋理解,scala是沒有static這一個關鍵字的。若是要使用單例,那更簡單,直接定義一個object就好了。

object Timer {
  var count = 0

  def currentCount(): Long = {
    count += 1
    count
  }
}
能夠這樣使用:

scala> Timer.currentCount()
res0: Long = 1

接下來講個比較經常使用的語法糖吧,那就是object的apply方法。當一個類只有一個用途的時候,就能夠用它。

scala> class Foo {}
defined class Foo

//有一個apply方法
scala> object FooMaker {
     |   def apply() = new Foo
     | }
defined module FooMaker

//新建object,自動得就調用了apply
scala> val newFoo = FooMaker() //賦值的對象是Foo,由於調用了FooMaker()的apply 
newFoo: Foo = Foo@5b83f762

看上面的代碼,object是不用new出來而能夠直接就用的。而用的時候,其實就默認調用了這個object的apply方法。

有沒有以爲很熟悉,這其實就是工廠模式

OK,這些就是scala裏面,有關面向對象的一些基礎知識,固然還有更高階的,好比集合和多態,這些後面用到的時候再說吧。

結語

本次介紹了scala的基礎變量和類型,scala默認是更加推薦使用不可變的變量,而常見的數據類型和java基本差很少,只是名字和用法上有些差異。

而在面向對象這一塊上,也基本和java差很少,只要有java的基礎,熟悉這部分的語法應該不是問題。

那麼按個人理解來講說爲何scala會有這些改動吧。首先,scala是在java發明後才被建立出來的,其設計理念必然會比java成熟一些,因此也就會想解決一些java的缺陷,好比說java某些語法較爲冗餘。而scala則較爲靈活一些,好比多了object,不須要每次都new一個對象,再好比有交互式環境。

其次,scala也是爲了貼近於函數式編程,函數式的核心,就是編寫無反作用代碼。而更本質地說,就是將代碼拆分模塊化,各個模塊各司其職,不是本身的別瞎動,本身管好本身的事,這個其實和微服務的思想是同樣的。

因此scala纔會默認得讓變量是不可變的,就是爲了儘可能讓代碼保持不變。

OK,那今天就先說到這吧,下次再說scala語法的重頭戲,集合和函數。

相關文章
相關標籤/搜索