Scala函數(shù)式編程專題--scala基礎(chǔ)語法介紹
上次我們介紹了函數(shù)式編程的好處,并使用scala寫了一個(gè)小小的例子幫助大家理解,從這里開始我將真正開始介紹scala編程的一些內(nèi)容。
這里會(huì)先重點(diǎn)介紹scala的一些語法。當(dāng)然,這里是假設(shè)你有一些java或者python的基礎(chǔ),畢竟大部分人不會(huì)將scala當(dāng)作第一門學(xué)習(xí)編程的語言。
不過這些語法知識(shí)記不住也沒關(guān)系,本身語法這種東西就應(yīng)該在使用中被記住。這里寫這篇的目的也只是梳理一遍,方便大家對(duì)語法有個(gè)初步的印象,后面可以隨時(shí)查詢。
PS:所使用的版本是scala 2.11.8,那我們開始吧
一.scala兩種運(yùn)行方式
首先,scala有兩種運(yùn)行方式,分別是在交互式環(huán)境運(yùn)行,以及通過腳本的方式運(yùn)行。先運(yùn)行一下吧,在scala安裝目錄下有一個(gè)bin文件夾,在這個(gè)文件夾雙擊scala.bat(Windows系統(tǒng)),就可以啟動(dòng)scala交互環(huán)境。當(dāng)然,一般在安裝scala,都會(huì)將“scala目錄/bin”加入到系統(tǒng)的Path變量中,這個(gè)時(shí)候直接運(yùn)行cmd,然后輸入scala就可以了。
因?yàn)閟cala也是運(yùn)行在jvm平臺(tái)上的,所以用腳本方式的話,類似于java那樣,需要先編譯再執(zhí)行。但是一般我們都會(huì)使用IDE來處理。通過我個(gè)人是更加喜歡idea的,只要下載免費(fèi)的社區(qū)版就可以滿足日常開發(fā)需求。
二.scala變量和類型
2.1 變量
首先,我們先來用一個(gè)例子來看看具體語法。在交互式環(huán)境中輸出hello world。
//聲明一個(gè)字符串 scala> val str = "Hello world" str: String = Hello world //打印 scala> println(str) Hello world
相信大家看一眼就能明白這兩行代碼是干嘛的,那我就說一點(diǎn)看不出來的。
scala聲明一個(gè)變量可以用val和var。val意為這個(gè)變量是不可變的,var意為這個(gè)變量是可變的。
scala> val num = 1; //聲明一個(gè)不可變的數(shù)值型變量 num: Int = 1 scala> num = 2 //因?yàn)椴豢勺?,所以要更改時(shí),出錯(cuò)了 <console>:12: error: reassignment to val num = 2 ^ scala> var num_var = 1; //聲明一個(gè)可變的數(shù)值型變量 num_var: Int = 1 scala> num_var = 2; //可以改變 num_var: Int = 2
從功能上來說,類似于java的final關(guān)鍵字。而且scala語言傾向于讓你多使用val,而少用var。
為什么呢?
因?yàn)槟軌蚋奖愕檬褂貌l(fā),在java的并發(fā)編程中,最喜歡的就是final的變量,因?yàn)樗际遣蛔兊?,隨便怎么用就怎么用。而scala所支持的函數(shù)式編程,天然就適合異步和并發(fā),所以做了這樣的處理,包括scala的集合類,默認(rèn)也是不可變的類型,如果要使用可變的集合,需要手動(dòng)指定。
2.2 scala數(shù)據(jù)類型
說完了變量,再來說說scala的數(shù)據(jù)類型。這里直接上一張圖。
這張圖說明了scala的數(shù)據(jù)類型繼承關(guān)系,我們先看最上面的Any類型,Any類型是所有數(shù)據(jù)類型的爸爸,在它里面定義了equals,toString這些方法,類似于java的object。這一點(diǎn)和java還是比較類似的。
然后接著往下看,Any又有兩個(gè)字類,左邊的AnyVal以及右邊的AnyRef。右邊的先不管,那個(gè)主要是集合那邊的知識(shí),我們只看左邊的。
AnyVal又被多個(gè)數(shù)據(jù)類型繼承,這些就是日常常用的一些數(shù)據(jù)類型了,可以看到和Java類似,都是Int,Double,Long這些。對(duì)了,這些數(shù)據(jù)類型,Int,Double,Long什么的,都是類,不像java,還有分int和Integer。
最后再來看看最下面的Nothing和Null吧,把這倆貨擱在一塊說是因?yàn)檫@幾個(gè)概念非常容易混淆,我自己要用的時(shí)候還得去查清楚了。
- java的null(scala也可以用,不過n是小寫):就是代表沒有任何東西,即空。一般新建一個(gè)對(duì)象,默認(rèn)值就是這貨。
- scala的Nothing:所有數(shù)據(jù)類型的子類,沒有具體的值可以對(duì)應(yīng)到這種類型,也就是說你沒法為Nothing類型賦值,包括null也不行。那可能有的小伙伴就會(huì)問了,那要這個(gè)玩意干嘛呢?一般嘛,try catch的返回值就是這種類型,還有程序exit的時(shí)候也是返回它,大概就是在不需要返回值的時(shí)候,就返回這個(gè)意思意思。
- scala的Null(注意大小寫):是所有集合類的子類,這種類型只能使用null來賦值,可以說基本沒什么卵用。只要知道有這么個(gè)東西就行。
三.scala面向?qū)ο缶幊?/strong>
是的,你沒看錯(cuò),雖然這里是用scala來進(jìn)行函數(shù)式編程,但scala也同樣提供了OOP的能力,后面有很大的概率也會(huì)說到,我們就順帶著簡(jiǎn)單介紹一下吧。
還是和java中的概念類似,只不過名字稍稍有些變化。對(duì)應(yīng)過來大概是這樣的:
- java的interface -> scala的trait (其實(shí)trait更類似abstract class)
- java的abstract class -> 一樣是abstract class
- java的class -> scala的class和object(關(guān)于class和object的區(qū)別,會(huì)在后面說)
其中,雖然說java的接口對(duì)應(yīng)的是scala的trait,但trait這個(gè)東西其實(shí)和interface還是有很多不一樣的,比如可以定義變量,可以直接定義方法內(nèi)容等。當(dāng)然,沒有構(gòu)造器和無法接收參數(shù)這個(gè)還是不變滴。
trait Car { val brand: String } trait Shiny { val shineRefraction: Int } class BMW extends Car { val brand = "BMW" } //通過with關(guān)鍵字,一個(gè)類可以擴(kuò)展多個(gè)特質(zhì): class BMW extends Car with Shiny { val brand = "BMW" val shineRefraction = 12 }
接下來重點(diǎn)說說class和object。
在scala中,是沒有static這個(gè)關(guān)鍵字的,那么這樣一來,很多java的功能就都沒法實(shí)現(xiàn),比如靜態(tài)方法,或者是單例模式,或者是沒有main方法。這個(gè)時(shí)候,object就出現(xiàn)了。
每個(gè)class都可以有一個(gè)同名的object,這個(gè)object被稱之為伴生對(duì)象(companion class)。class和object可以互相訪問對(duì)方的私有成員(public,private這些權(quán)限訪問和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對(duì)象,直接使用toJsonObject方法。 } }
得益于object,我們可以像調(diào)用java靜態(tài)方法一樣地寫scala代碼,而這一切,都要?dú)w功于object。
因?yàn)?!object里面的變量,或是方法,都是static的,這里說的static是方便有java基礎(chǔ)的童鞋理解,scala是沒有static這一個(gè)關(guān)鍵字的。如果要使用單例,那更簡(jiǎn)單,直接定義一個(gè)object就行了。
object Timer { var count = 0 def currentCount(): Long = { count += 1 count } } 可以這樣使用: scala> Timer.currentCount() res0: Long = 1
接下來說個(gè)比較常用的語法糖吧,那就是object的apply方法。當(dāng)一個(gè)類只有一個(gè)用途的時(shí)候,就可以用它。
scala> class Foo {} defined class Foo //有一個(gè)apply方法 scala> object FooMaker { | def apply() = new Foo | } defined module FooMaker //新建object,自動(dòng)得就調(diào)用了apply scala> val newFoo = FooMaker() //賦值的對(duì)象是Foo,因?yàn)檎{(diào)用了FooMaker()的apply newFoo: Foo = Foo@5b83f762
看上面的代碼,object是不用new出來而可以直接就用的。而用的時(shí)候,其實(shí)就默認(rèn)調(diào)用了這個(gè)object的apply方法。
有沒有覺得很熟悉,這其實(shí)就是工廠模式。
OK,這些就是scala里面,有關(guān)面向?qū)ο蟮囊恍┗A(chǔ)知識(shí),當(dāng)然還有更高階的,比如集合和多態(tài),這些后面用到的時(shí)候再說吧。
結(jié)語
本次介紹了scala的基礎(chǔ)變量和類型,scala默認(rèn)是更加推薦使用不可變的變量,而常見的數(shù)據(jù)類型和java基本差不多,只是名字和用法上有些差別。
而在面向?qū)ο筮@一塊上,也基本和java差不多,只要有java的基礎(chǔ),熟悉這部分的語法應(yīng)該不是問題。
那么按我的理解來說說為什么scala會(huì)有這些改動(dòng)吧。首先,scala是在java發(fā)明后才被創(chuàng)建出來的,其設(shè)計(jì)理念必然會(huì)比java成熟一些,所以也就會(huì)想解決一些java的缺陷,比如說java某些語法較為冗余。而scala則較為靈活一些,比如多了object,不需要每次都new一個(gè)對(duì)象,再比如有交互式環(huán)境。
其次,scala也是為了貼近于函數(shù)式編程,函數(shù)式的核心,就是編寫無副作用代碼。而更本質(zhì)地說,就是將代碼拆分模塊化,各個(gè)模塊各司其職,不是自己的別瞎動(dòng),自己管好自己的事,這個(gè)其實(shí)和微服務(wù)的思想是一樣的。
所以scala才會(huì)默認(rèn)得讓變量是不可變的,就是為了盡量讓代碼保持不變。
OK,那今天就先說到這吧,下次再說scala語法的重頭戲,集合和函數(shù)。
以上就是scala函數(shù)式編專題——scala基礎(chǔ)語法介紹的詳細(xì)內(nèi)容,更多關(guān)于scala函數(shù)式編程的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Scala函數(shù)式編程專題--scala集合和函數(shù)
這篇文章主要介紹了scala集合和函數(shù)的的相關(guān)資料,文中示例代碼非常詳細(xì),幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-06-06權(quán)限控制之粗粒度與細(xì)粒度概念及實(shí)現(xiàn)簡(jiǎn)單介紹
這篇文章主要介紹了權(quán)限控制之粗粒度與細(xì)粒度概念及實(shí)現(xiàn)簡(jiǎn)單介紹,具有一定參考價(jià)值,需要的朋友可以了解下。2017-10-10Cordova插件實(shí)現(xiàn)JavaScript與Java的通信的詳細(xì)過程
本文將結(jié)合最常用的華為推送服務(wù)Cordova插件,介紹HMS Core用到的JS-Java消息交互方式,講解在JS側(cè)如何調(diào)用Java側(cè)接口,最終實(shí)現(xiàn)HMS Core能力,感興趣的朋友一起學(xué)習(xí)下吧2021-06-06bilibili彈幕轉(zhuǎn)ass程序制作思路及過程
本文主要是為了方便線下播放Bilibili的彈幕,而專門制作的一款將彈幕轉(zhuǎn)換為ASS的程序,介紹了程序制作的思路及過程,有需要的朋友可以參考下2014-09-09ffmpeg播放器實(shí)現(xiàn)詳解之視頻顯示(推薦)
FFmpeg是一套可以用來記錄、轉(zhuǎn)換數(shù)字音頻、視頻,并能將其轉(zhuǎn)化為流的開源計(jì)算機(jī)程序。這篇文章主要介紹了ffmpeg播放器實(shí)現(xiàn)詳解視頻顯示,需要的朋友可以參考下2020-07-07