版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第2章Scala語言基礎(chǔ)
《Spark編程基礎(chǔ)》課程配套授課視頻提綱2.1Scala語言概述2.2Scala基礎(chǔ)2.3面向?qū)ο缶幊袒A(chǔ)2.4函數(shù)式編程基礎(chǔ)百度搜索廈門大學(xué)數(shù)據(jù)庫實驗室網(wǎng)站訪問平臺2.1Scala語言概述2.1.1計算機(jī)的緣起2.1.2編程范式2.1.3Scala簡介2.1.1計算機(jī)的緣起數(shù)學(xué)家阿隆佐?邱奇(AlonzoChurch)設(shè)計了“λ演算”,這是一套用于研究函數(shù)定義、函數(shù)應(yīng)用和遞歸的形式系統(tǒng)λ演算被視為最小的通用程序設(shè)計語言λ演算的通用性就體現(xiàn)在,任何一個可計算函數(shù)都能用這種形式來表達(dá)和求值λ演算是一個數(shù)理邏輯形式系統(tǒng),強(qiáng)調(diào)的是變換規(guī)則的運(yùn)用,而非實現(xiàn)它們的具體機(jī)器2.1.1計算機(jī)的緣起英國數(shù)學(xué)家阿蘭·圖靈采用了完全不同的設(shè)計思路,提出了一種全新的抽象計算模型——圖靈機(jī)圖靈機(jī)是現(xiàn)代計算機(jī)的鼻祖?,F(xiàn)有理論已經(jīng)證明,λ演算和圖靈機(jī)的計算能力是等價的2.1.1計算機(jī)的緣起馮·諾依曼(JohnVonNeumann)將圖靈的理論物化成為實際的物理實體,成為了計算機(jī)體系結(jié)構(gòu)的奠基者1945年6月,馮·諾依曼提出了在數(shù)字計算機(jī)內(nèi)部的存儲器中存放程序的概念,這是所有現(xiàn)代計算機(jī)的范式,被稱為“馮·諾依曼結(jié)構(gòu)”2.1.2編程范式編程范式是指計算機(jī)編程的基本風(fēng)格或典范模式。常見的編程范式主要包括命令式編程和函數(shù)式編程。面向?qū)ο缶幊叹蛯儆诿钍骄幊蹋热鏑++、Java等命令式語言是植根于馮·諾依曼體系的,一個命令式程序就是一個馮·諾依曼機(jī)的指令序列,給機(jī)器提供一條又一條的命令序列讓其原封不動地執(zhí)行函數(shù)式編程,又稱泛函編程,它將計算機(jī)的計算視為數(shù)學(xué)上的函數(shù)計算函數(shù)編程語言最重要的基礎(chǔ)是λ演算。典型的函數(shù)式語言包括Haskell、Erlang和Lisp等2.1.2編程范式一個很自然的問題是,既然已經(jīng)有了命令式編程,為什么還需要函數(shù)式編程呢?為什么在C++、Java等命令式編程流行了很多年以后,近些年函數(shù)式編程會迅速升溫呢?命令式編程涉及多線程之間的狀態(tài)共享,需要鎖機(jī)制實現(xiàn)并發(fā)控制函數(shù)式編程不會在多個線程之間共享狀態(tài),不需要用鎖機(jī)制,可以更好并行處理,充分利用多核CPU并行處理能力2.1.3Scala簡介Scala是一門類Java的多范式語言,它整合了面向?qū)ο缶幊毯秃瘮?shù)式編程的最佳特性。具體來講:Scala運(yùn)行于Java虛擬機(jī)(JVM)之上,并且兼容現(xiàn)有的Java程序Scala是一門純粹的面向?qū)ο蟮恼Z言Scala也是一門函數(shù)式語言MartinOderskyScala之父詹姆斯·高斯林Java之父”IfIweretopickalanguagetousetodayotherthanJava,itwouldbeScala.”
—JamesGosling
2.1.4Scala的安裝和使用方法
安裝Java
安裝Scala
使用Scala解釋器
第1個Scala程序:HelloWorld具體可以參照廈門大學(xué)數(shù)據(jù)庫實驗室網(wǎng)站博客:/blog/929-2/平臺每年訪問量超過100萬次
安裝Java直接通過命令安裝OpenJDK7配置JAVA_HOME環(huán)境變量使配置立即生效:
安裝Scala登錄Scala官網(wǎng),下載scala-2.11.8.tgz把scala命令添加到path環(huán)境變量中啟動Scala解釋器:
使用Scala解釋器在Shell命令提示符界面中輸入“scala”命令后,會進(jìn)入scala命令行提示符狀態(tài):可以使用命令“:quit”退出Scala解釋器,如下所示:
使用Scala解釋器(續(xù))用“:load”命令導(dǎo)入腳本,一次運(yùn)行多行程序:使用文本編輯器(比如vim)創(chuàng)建一個代碼文件Test.scala在ScalaREPL中執(zhí)行如下命令運(yùn)行該代碼文件:
第1個Scala程序:HelloWorld通過編譯打包的方式運(yùn)行Scala程序使用scalac命令進(jìn)行編譯(編譯的結(jié)果為java字節(jié)碼)使用scala或者java運(yùn)行字節(jié)碼文件2.2Scala基礎(chǔ)2.2.1基本數(shù)據(jù)類型和變量2.2.2輸入輸出2.2.3控制結(jié)構(gòu)2.2.4數(shù)據(jù)結(jié)構(gòu)
2.2.1基本數(shù)據(jù)類型和變量基本數(shù)據(jù)類型
基本操作
變量
基本數(shù)據(jù)類型Scala的數(shù)據(jù)類型包括:Byte、Char、Short、Int、Long、Float、Double和Boolean(注意首字母大寫)和Java不同的是,在Scala中,這些類型都是“類”,并且都是包scala的成員,比如,Int的全名是scala.Int。對于字符串,Scala用java.lang.String類來表示字符串
基本數(shù)據(jù)類型字面量(literal)
基本操作在Scala中,操作符就是方法。例如,5+3和(5).+(3)是等價的等價于算術(shù)運(yùn)算符:加(+)、減(-)、乘(*)、除(/)、余數(shù)(%);關(guān)系運(yùn)算符:大于(>)、小于(<)、等于(==)、不等于(!=)、大于等于(>=)、小于等于(<=)邏輯運(yùn)算符:邏輯與(&&)、邏輯或(||)、邏輯非(!);位運(yùn)算符:按位與(&)、按位或(|)、按位異或(^)、按位取反(~)等賦值運(yùn)算符:=及其與其它運(yùn)算符結(jié)合的擴(kuò)展賦值運(yùn)算符,例如+=、%=。操作符優(yōu)先級:算術(shù)運(yùn)算符>關(guān)系運(yùn)算符>邏輯運(yùn)算符>賦值運(yùn)算符
基本操作富包裝類對于基本數(shù)據(jù)類型,除了以上提到的各種操作符外,Scala還提供了許多常用運(yùn)算的方法,只是這些方法不是在基本類里面定義,還是被封裝到一個對應(yīng)的富包裝類中每個基本類型都有一個對應(yīng)的富包裝類,例如Int有一個RichInt類、String有一個RichString類,這些類位于包scala.runtime中當(dāng)對一個基本數(shù)據(jù)類型的對象調(diào)用其富包裝類提供的方法,Scala會自動通過隱式轉(zhuǎn)換將該對象轉(zhuǎn)換為對應(yīng)的富包裝類型,然后再調(diào)用相應(yīng)的方法。例如:3max5
變量Scala有兩種類型的變量:val:是不可變的,在聲明時就必須被初始化,而且初始化以后就不能再賦值;var:是可變的,聲明的時候需要進(jìn)行初始化,初始化以后還可以再次對其賦值?;菊Z法:val變量名:數(shù)據(jù)類型=初始值var變量名:數(shù)據(jù)類型=初始值
變量類型推斷機(jī)制(typeinference):根據(jù)初始值自動推斷變量的類型,使得定義變量時可以省略具體的數(shù)據(jù)類型及其前面的冒號
變量注意:在REPL環(huán)境下,可以重復(fù)使用同一個變量名來定義變量,而且變量前的修飾符和其類型都可以不一致,REPL會以最新的一個定義為準(zhǔn)2.2.2輸入輸出控制臺輸入輸出語句
讀寫文件
控制臺輸入輸出語句從控制臺讀寫數(shù)據(jù)方法:readInt、readDouble、readByte、readShort、readFloat、readLong、readCharreadBoolean及readLine,分別對應(yīng)9種基本數(shù)據(jù)類型,其中前8種方法沒有參數(shù),readLine可以不提供參數(shù),也可以帶一個字符串參數(shù)的提示所有這些函數(shù)都屬于對象scala.io.StdIn的方法,使用前必須導(dǎo)入,或者直接用全稱進(jìn)行調(diào)用控制臺輸入輸出語句Tips:讀取數(shù)據(jù)時看不到輸入的解決辦法。用-Xnojline選項禁用控制臺讀寫庫Jline,但這時又不能用箭頭調(diào)用命令歷史,所以還需要一個小工具rlwrap。完整命令為“rlwrap
scala-Xnojline”,如果提示rlwrap
沒有安裝,請按提示進(jìn)行安裝。
控制臺輸入輸出語句向控制臺輸出信息方法:print()和println(),可以直接輸出字符串或者其它數(shù)據(jù)類型,其中println在末尾自動換行。
控制臺輸入輸出語句C語言風(fēng)格格式化字符串的printf()函數(shù)print()、println()和printf()都在對象Predef中定義,該對象默認(rèn)情況下被所有Scala程序引用,因此可以直接使用Predef對象提供的方法,而無需使用scala.Predef.的形式。
控制臺輸入輸出語句s字符串和f字符串:Scala提供的字符串插值機(jī)制,以方便在字符串字面量中直接嵌入變量的值?;菊Z法:s"…$變量名…"或f"…$變量名%格式化字符…"
讀寫文件寫入文件Scala需要使用java.io.PrintWriter實現(xiàn)把數(shù)據(jù)寫入到文件,PrintWriter類提供了print和println兩個寫方法
讀寫文件讀取文件可以使用Scala.io.Source的getLines方法實現(xiàn)對文件中所有行的讀取2.2.3控制結(jié)構(gòu)if條件表達(dá)式while循環(huán)for循環(huán)異常處理對循環(huán)的控制if條件表達(dá)式有一點與Java不同的是,Scala中的if表達(dá)式的值可以賦值給變量while循環(huán)for循環(huán)基本語法其中,“變量<-表達(dá)式”被稱為“生成器(generator)”for循環(huán)“守衛(wèi)(guard)”的表達(dá)式:過濾出一些滿足條件的結(jié)果?;菊Z法:for(變量<-表達(dá)式if
條件表達(dá)式)語句塊for循環(huán)Scala也支持“多個生成器”的情形,可以用分號把它們隔開,比如:for循環(huán)for結(jié)構(gòu)可以在每次執(zhí)行的時候創(chuàng)造一個值,然后將包含了所有產(chǎn)生值的集合作為for循環(huán)表達(dá)式的結(jié)果返回,集合的類型由生成器中的集合類型確定。for(變量<-表達(dá)式)yield
{語句塊}for推導(dǎo)式
異常處理Scala仍使用try-catch結(jié)構(gòu)來捕獲異常importjava.io.FileReaderimportjava.io.FileNotFoundExceptionimportjava.io.IOExceptiontry
{
valf=newFileReader("input.txt")
//文件操作}
catch
{
caseex:FileNotFoundException=>
//文件不存在時的操作
caseex:IOException=>
//發(fā)生I/O錯誤時的操作}finally
{
file.close()//確保關(guān)閉文件}
Scala不支持Java中的“受檢查異?!?checkedexception),將所有異常都當(dāng)作“不受檢異?!保ɑ蚍Q為運(yùn)行時異常)
對循環(huán)的控制為了提前終止整個循環(huán)或者跳到下一個循環(huán),Scala沒有break和continue關(guān)鍵字。Scala提供了一個Breaks類(位于包scala.util.control)。Breaks類有兩個方法用于對循環(huán)結(jié)構(gòu)進(jìn)行控制,即breakable和break:將需要控制的語句塊作為參數(shù)放在breakable后面,然后,其內(nèi)部在某個條件滿足時調(diào)用break方法,程序?qū)⑻鯾reakable方法。
對循環(huán)的控制2.2.4數(shù)據(jù)結(jié)構(gòu)
數(shù)組(Array)
元組(Tuple)
容器(Collection)
序列(Sequence)集合(Set)
映射(Map)
迭代器(Iterator)
數(shù)組(Array)數(shù)組:一種可變的、可索引的、元素具有相同類型的數(shù)據(jù)集合。Scala提供了參數(shù)化類型的通用數(shù)組類Array[T],其中T可以是任意的Scala類型,可以通過顯式指定類型或者通過隱式推斷來實例化一個數(shù)組??梢圆唤o出數(shù)組類型,Scala會自動根據(jù)提供的初始化數(shù)據(jù)來推斷出數(shù)組的類型
數(shù)組(Array)多維數(shù)組的創(chuàng)建:調(diào)用Array的ofDim方法valmyMatrix=Array.ofDim[Int](3,4)//類型實際就是Array[Array[Int]]valmyCube=Array.ofDim[String](3,2,4)//類型實際是Array[Array[Array[Int]]]可以使用多級圓括號來訪問多維數(shù)組的元素,例如myMatrix(0)(1)返回第一行第二列的元素
元組(Tuple)元組是對多個不同類型對象的一種簡單封裝。定義元組最簡單的方法就是把多個元素用逗號分開并用圓括號包圍起來。使用下劃線“_”加上從1開始的索引值,來訪問元組的元素。如果需要在方法里返回多個不同類型的對象,Scala可以通過返回一個元組實現(xiàn)。
容器(collection)Scala提供了一套豐富的容器(collection)庫,包括序列(Sequence)、集合(Set)、映射(Map)等。Scala用了三個包來組織容器類,分別是scala.collection、scala.collection.mutable和scala.collection.immutable。scala.collection包中的容器通常都具備對應(yīng)的不可變實現(xiàn)和可變實現(xiàn)。
容器(collection)scala.collection包中容器的宏觀層次結(jié)構(gòu)
序列(Sequence)序列(Sequence):元素可以按照特定的順序訪問的容器。序列中每個元素均帶有一個從0開始計數(shù)的固定索引位置。序列容器的根是collection.Seq特質(zhì)。其具有兩個子特質(zhì)LinearSeq和IndexedSeq。LinearSeq序列具有高效的head和tail操作,而IndexedSeq序列具有高效的隨機(jī)存儲操作。實現(xiàn)了特質(zhì)LinearSeq的常用序列有列表(List)和隊列(Queue)。實現(xiàn)了特質(zhì)IndexedSeq的常用序列有可變數(shù)組(ArrayBuffer)和向量(Vector)。
序列---列表(List)列表:一種共享相同類型的不可變的對象序列。定義在scala.collection.immutable包中不同于Java的java.util.List,scala的List一旦被定義,其值就不能改變,因此聲明List時必須初始化varstrList=List("BigData","Hadoop","Spark")列表有頭部和尾部的概念,可以分別使用head和tail方法來獲取head返回的是列表第一個元素的值tail返回的是除第一個元素外的其它值構(gòu)成的新列表,這體現(xiàn)出列表具有遞歸的鏈表結(jié)構(gòu)strList.head將返回字符串”BigData”,strList.tail返回List("Hadoop","Spark")
序列---列表(List)Scala還定義了一個空列表對象Nil,借助Nil,可以將多個元素用操作符::串起來初始化一個列表valintList=1::2::3::Nil與valintList=List(1,2,3)等效構(gòu)造列表常用的方法是通過在已有列表前端增加元素,使用的操作符為::,例如:valotherList="Apache"::strList執(zhí)行該語句后strList保持不變,而otherList將成為一個新的列表:List("Apache","BigData","Hadoop","Spark")注意:除了head、tail操作是常數(shù)時間O(1),其它按索引訪問的操作都需要從頭開始遍歷,因此是線性時間復(fù)雜度O(N)。2.2.4.4序列---向量(vector)Vetor可以實現(xiàn)所有訪問操作都是常數(shù)時間。2.2.4.4序列---ListBuffer和ArrayBufferListBuffer和ArrayBuffer是List和Vector對應(yīng)的可變版本,這兩個序列都位于scala.collection.mutable中。常用操作符:+=Insert-=remove2.2.4.4序列---RangeRange類:一種特殊的、帶索引的不可變數(shù)字等差序列。其包含的值為從給定起點按一定步長增長(減小)到指定終點的所有數(shù)值。Range可以支持創(chuàng)建不同數(shù)據(jù)類型的數(shù)值序列,包括Int、Long、Float、Double、Char、BigInt和BigDecimal等(1)創(chuàng)建一個從1到5的數(shù)值序列,包含區(qū)間終點5,步長為12.2.4.4序列---Range(2)創(chuàng)建一個從1到5的數(shù)值序列,不包含區(qū)間終點5,步長為1(3)創(chuàng)建一個從1到10的數(shù)值序列,包含區(qū)間終點10,步長為2(4)創(chuàng)建一個Float類型的數(shù)值序列,從0.5f到5.9f,步長為0.3f
集合(Set)集合(set):不重復(fù)元素的容器(collection)。列表中的元素是按照插入的先后順序來組織的,但是,“集合”中的元素并不會記錄元素的插入順序,而是以“哈希”方法對元素的值進(jìn)行組織,所以,它允許你快速地找到某個元素集合包括可變集和不可變集,分別位于scala.collection.mutable包和scala.collection.immutable包,缺省情況下創(chuàng)建的是不可變集varmySet=Set("Hadoop","Spark")mySet+="Scala"
如果要聲明一個可變集,則需要提前引入scala.collection.mutable.Setimportscala.collection.mutable.SetvalmyMutableSet=Set("Database","BigData")myMutableSet+="CloudComputing"
映射(Map)映射(Map):一系列鍵值對的容器。鍵是唯一的,但值不一定是唯一的。可以根據(jù)鍵來對值進(jìn)行快速的檢索Scala的映射包含了可變的和不可變的兩種版本,分別定義在包scala.collection.mutable和scala.collection.immutable里。默認(rèn)情況下,Scala中使用不可變的映射。如果想使用可變映射,必須明確地導(dǎo)入scala.collection.mutable.Mapvaluniversity=Map("XMU"->"XiamenUniversity","THU"->"TsinghuaUniversity","PKU"->"PekingUniversity")
映射(Map)如果要獲取映射中的值,可以通過鍵來獲取對于這種訪問方式,如果給定的鍵不存在,則會拋出異常,為此,訪問前可以先調(diào)用contains方法確定鍵是否存在
映射(Map)可變的映射也可以使用+=操作來添加新的元素
迭代器(Iterator)迭代器(Iterator)不是一個容器,而是提供了按順序訪問容器元素的數(shù)據(jù)結(jié)構(gòu)。
迭代器包含兩個基本操作:next和hasNext。next可以返回迭代器的下一個元素,hasNext用于檢測是否還有下一個元素建議:除next和hasnext方法外,在對一個迭代器調(diào)用了某個方法后,不要再次使用該迭代器。2.3面向?qū)ο缶幊袒A(chǔ)2.3.1類2.3.2對象2.3.3繼承2.3.4參數(shù)化類型2.3.5特質(zhì)2.3.6模式匹配2.3.7包2.3.1類
類的定義
類成員的可見性
方法的定義
構(gòu)造器
類的定義類的定義:字段用val或var關(guān)鍵字進(jìn)行定義方法定義:def
方法名(參數(shù)列表):返回結(jié)果類型={方法體}
類的定義使用new關(guān)鍵字創(chuàng)建一個類的實例。
類成員的可見性Scala類中所有成員的默認(rèn)可見性為公有,任何作用域內(nèi)都能直接訪問公有成員。除了默認(rèn)的公有可見性,Scala也提供private和protected,其中,private成員只對本類型和嵌套類型可見;protected成員對本類型和其繼承類型都可見。為了避免直接暴露public字段,建議將字段設(shè)置為private,對于private字段,Scala采用類似Java中的getter和setter方法,定義了兩個成對的方法value和value_=進(jìn)行讀取和修改。
類成員的可見性Scala語法中有如下規(guī)范,當(dāng)編譯器看到以value和value_=這種成對形式出現(xiàn)的方法時,它允許用戶去掉下劃線_,而采用類似賦值表達(dá)式的形式
方法的定義基本語法:def
方法名(參數(shù)列表):返回結(jié)果類型={方法體}方法參數(shù)前不能加上val或var,所有的方法參數(shù)都是不可變類型。無參數(shù)的方法定義時可以省略括號,這時調(diào)用時也不能帶有括號;如果定義時帶有括號,則調(diào)用時可以帶括號,也可以不帶括號。方法名后面的圓括號()可以用大括號{}來代替。如果方法只有一個參數(shù),可以省略點號(.)而采用中綴操作符調(diào)用方法。如果方法體只有一條語句,可以省略方法體兩邊的大括號
方法的定義
方法的定義當(dāng)方法的返回結(jié)果類型可以從最后的表達(dá)式推斷出時,可以省略結(jié)果類型;如果方法返回類型為Unit,可以同時省略返回結(jié)果類型和等號,但不能省略大括號。Scala允許方法重載。只要方法的完整簽名(包括方法名、參數(shù)類型列表、返回類型)是唯一的,多個方法可以使用相同的方法名。構(gòu)造器Scala類的定義主體就是類的構(gòu)造器,稱為主構(gòu)造器。在類名之后用圓括號列出主構(gòu)造器的參數(shù)列表。主構(gòu)造器的參數(shù)前可以使用val或var關(guān)鍵字,Scala內(nèi)部將自動為這些參數(shù)創(chuàng)建私有字段,并提供對應(yīng)的訪問方法如果不希望將構(gòu)造器參數(shù)成為類的字段,只需要省略關(guān)鍵字var或者val
構(gòu)造器Scala類可以包含零個或多個輔助構(gòu)造器(auxiliaryconstructor)。輔助構(gòu)造器使用this進(jìn)行定義,this的返回類型為Unit。每個輔助構(gòu)造器的第一個表達(dá)式必須是調(diào)用一個此前已經(jīng)定義的輔助構(gòu)造器或主構(gòu)造器,調(diào)用的形式為“this(參數(shù)列表)”
構(gòu)造器2.3.2對象
單例對象
伴生對象
應(yīng)用程序?qū)ο骯pply方法和update方法
單例對象Scala采用單例對象(singletonobject)來實現(xiàn)與Java靜態(tài)成員同樣的功能。使用object關(guān)鍵字定義單例對象。單例對象的使用與一個普通的類實例一樣:
單例對象---伴生對象和孤立對象當(dāng)一個單例對象和它的同名類一起出現(xiàn)時,這時的單例對象被稱為這個同名類的“伴生對象”
(companionobject)。相應(yīng)的類被稱為這個單例對象的“伴生類”類和它的伴生對象必須存在于同一個文件中,可以相互訪問私有成員。沒有同名類的單例對象,被稱為孤立對象(standaloneobject)。一般情況下,Scala程序的入口點main方法就是定義在一個孤立對象里。
單例對象---伴生對象和孤立對象apply方法和update方法思考下行代碼的執(zhí)行過程:Scala自動調(diào)用Array類的伴生對象Array中的一個稱為apply的方法,來創(chuàng)建一個Array對象myStrArr。apply方法調(diào)用約定:用括號傳遞給類實例或單例對象名一個或多個參數(shù)時,Scala會在相應(yīng)的類或?qū)ο笾胁檎曳椒麨閍pply且參數(shù)列表與傳入的參數(shù)一致的方法,并用傳入的參數(shù)來調(diào)用該apply方法。apply方法和update方法例:類中的apply方法apply方法和update方法伴生對象中的apply方法:將所有類的構(gòu)造方法以apply方法的形式定義在伴生對象中,這樣伴生對象就像生成類實例的工廠,而這些apply方法也被稱為工廠方法。apply方法和update方法為什么要設(shè)計apply方法?保持對象和函數(shù)之間使用的一致性。面向?qū)ο螅骸皩ο?方法”VS數(shù)學(xué):“函數(shù)(參數(shù))”Scala中一切都是對象,包括函數(shù)也是對象。Scala中的函數(shù)既保留括號調(diào)用樣式,也可以使用點號調(diào)用形式,其對應(yīng)的方法名即為apply。Scala的對象也可以看成函數(shù),前提是該對象提供了apply方法apply方法和update方法update方法的調(diào)用約定:當(dāng)對帶有括號并包括一到若干參數(shù)的對象進(jìn)行賦值時,編譯器將調(diào)用對象的update方法,并將括號里的參數(shù)和等號右邊的值一起作為update方法的輸入?yún)?shù)來執(zhí)行調(diào)用。2.3.3繼承
抽象類
擴(kuò)展類
類層次結(jié)構(gòu)Option類
抽象類如果一個類包含沒有實現(xiàn)的成員,則必須使用abstract關(guān)鍵詞進(jìn)行修飾,定義為抽象類。關(guān)于上面的定義,說明幾點:
(1)定義一個抽象類,需要使用關(guān)鍵字abstract。
(2)定義一個抽象類的抽象方法,也不需要關(guān)鍵字abstract,只要把方法體空著,不寫方法體就可以。
(3)抽象類中定義的字段,只要沒有給出初始化值,就表示是一個抽象字段,但是,抽象字段必須要聲明類型,否則編譯會報錯。
擴(kuò)展類(子類)Scala只支持單一繼承,而不支持多重繼承。在類定義中使用extends關(guān)鍵字表示繼承關(guān)系。定義子類時,需要注意:重載父類的抽象成員(包括字段和方法)時,override關(guān)鍵字是可選的;而重載父類的非抽象成員時,override關(guān)鍵字是必選的。只能重載val類型的字段,而不能重載var類型的字段。因為var類型本身就是可變的,所以,可以直接修改它的值,無需重載;子類不僅僅可以派生自抽象類,還可以派生自非抽象類,如果某個類不希望被其它類派生出子類,則需要在類定義的class關(guān)鍵字前加上final關(guān)鍵字。子類如果沒有顯式地指明父類,則其默認(rèn)的父類為AnyRef。
擴(kuò)展類編譯執(zhí)行后,結(jié)果為:
類層級結(jié)構(gòu)
類層級結(jié)構(gòu)Null是所有引用類型的子類,其唯一的實例為null,表示一個“空”對象,可以賦值給任何引用類型的變量,但不能賦值給值類型的變量。Nothing是所有其它類型的子類,包括Null。Nothing沒有實例,主要用于異常處理函數(shù)的返回類型。
Option類Scala提供null是為了實現(xiàn)在JVM與其它Java庫的兼容性,但是,除非明確需要與Java庫進(jìn)行交互,否則,Scala建議盡量避免使用這種可能帶來bug的null,而改用Option類。Option是一個抽象類,有一個具體的子類Some和一個對象None,其中,前者表示有值的情形,后者表示沒有值。當(dāng)方法不確定是否有對象返回時,可以讓方法Option[T],其中,T為類型參數(shù)。對于這類方法,如果確實有T類型的對象需要返回,會將該對象包裝成一個Some對象并返回;如果沒有值需要返回,將返回None。
Option類2.3.4特質(zhì)(trait)
特質(zhì)概述
特質(zhì)的定義
把特質(zhì)混入類中
把多個特質(zhì)混入類中
特質(zhì)概述Java中提供了接口,允許一個類實現(xiàn)任意數(shù)量的接口。
Scala中沒有接口的概念,而是提供了“特質(zhì)(trait)”,它不僅實現(xiàn)了接口的功能,還具備了很多其他的特性Scala的特質(zhì)是代碼重用的基本單元,可以同時擁有抽象方法和具體方法Scala中,一個類只能繼承自一個超類,卻可以實現(xiàn)多個特質(zhì),從而重用特質(zhì)中的方法和字段,實現(xiàn)了多重繼承
特質(zhì)的定義特質(zhì)的定義:使用關(guān)鍵字trait。特質(zhì)既可以包含抽象成員,也可以包含非抽象成員。包含抽象成員時,也不需要abstract關(guān)鍵字。特質(zhì)可以使用extends繼承其它的特質(zhì),并且還可以繼承類。特質(zhì)的定義體就相當(dāng)于主構(gòu)造器,與類不同的是,不能給特質(zhì)的主構(gòu)造器提供參數(shù)列表,而且也不能為特質(zhì)定義輔助構(gòu)造器。
把特質(zhì)混入類中可以使用extends或with關(guān)鍵字把特質(zhì)混入類中。如果特質(zhì)中包含抽象成員,則該類必須為這些抽象成員提供具體實現(xiàn),除非該類被定義為抽象類。
把特質(zhì)混入類中特質(zhì)也可以當(dāng)做類型使用,即可以定義具有某種特質(zhì)類型的變量,并使用任何混入了相應(yīng)特質(zhì)的類的實例進(jìn)行初始化。
把特質(zhì)混入類中當(dāng)使用extends關(guān)鍵字混入特質(zhì)時,相應(yīng)的類就隱式地繼承了特質(zhì)的超類。如果想把特質(zhì)混入到需要顯式指定了父類的類里,則可以用extends指明待繼承的父類,再用with混入特質(zhì)。
把多個特質(zhì)混入類中如果要混入多個特質(zhì),可以連續(xù)使用多個with。2.3.5模式匹配match語句case類的匹配match語句最常見的模式匹配是match語句,match語句用在當(dāng)需要從多個分支中進(jìn)行選擇的場景。通配符_相當(dāng)于Java中的default分支。match結(jié)構(gòu)中不需要break語句來跳出判斷,Scala從前往后匹配到一個分支后,會自動跳出判斷。match語句case后面的表達(dá)式可以是任何類型的常量,而不要求是整數(shù)類型。match語句除了匹配特定的常量,還能匹配某種類型的所有值。match語句可以在match表達(dá)式的case中使用守衛(wèi)式(guard)添加一些過濾邏輯執(zhí)行結(jié)果:case類的匹配case類是一種特殊的類,它們經(jīng)過優(yōu)化以被用于模式匹配。當(dāng)定義一個類時,如果在class關(guān)鍵字前加上case關(guān)鍵字,則該類稱為case類。Scala為case類自動重載了許多實用的方法,包括toString、equals和hashcode方法。Scala為每一個case類自動生成一個伴生對象,其包括模板代碼一個apply方法,因此,實例化case類的時候無需使用new關(guān)鍵字;一個unapply方法,該方法包含一個類型為伴生類的參數(shù),返回的結(jié)果是Option類型,對應(yīng)的類型參數(shù)是N元組,N是伴生類中主構(gòu)造器參數(shù)的個數(shù)。Unapply方法用于對對象進(jìn)行解構(gòu)操作,在case類模式匹配中,該方法被自動調(diào)用,并將待匹配的對象作為參數(shù)傳遞給它。case類的匹配例如,假設(shè)有如下定義的一個case類:則編譯器自動生成的伴生對象是:case類的匹配每一個case子句中的Car(…),都會自動調(diào)用Car.unapply(car),并將提取到的值與Car后面括號里的參數(shù)進(jìn)行一一匹配比較。第一個case和第二個case是與特定的值進(jìn)行匹配。第三個case由于Car后面跟的參數(shù)是變量,因此將匹配任意的參數(shù)值。2.3.6包
包的定義
引用包成員
包的定義為了解決程序中命名沖突問題,Scala也和Java一樣采用包(package)來層次化、模塊化地組織程序。包可以包含類、對象和特質(zhì)的定義,但是不能包含函數(shù)或變量的定義。為了在任意位置訪問MyClass類,需要使用autodepartment.MyClass。Scala的包和源文件之間并沒有強(qiáng)制的一致層次關(guān)聯(lián)關(guān)系。
包的定義通過在關(guān)鍵字package后面加大括號,可以將程序的不同部分放在不同的包里。這樣可以實現(xiàn)包的嵌套,相應(yīng)的作用域也是嵌套的
引用包成員可以用import子句來引用包成員,這樣可以簡化包成員的訪問方式使用通配符下劃線(_)引入類或?qū)ο蟮乃谐蓡TScala隱式地添加了一些引用到每個程序前面,相當(dāng)于每個Scala程序都隱式地以如下代碼開始:2.4函數(shù)式編程基礎(chǔ)2.4.1函數(shù)定義與使用2.4.2針對集合的操作2.4.3函數(shù)式編程實例WordCount2.4.1函數(shù)定義與使用
函數(shù)式編程簡介
匿名函數(shù)
占位符語法
高階函數(shù)
閉包
函數(shù)式編程簡介函數(shù)式編程將計算視為數(shù)學(xué)上的函數(shù)計算函數(shù)成為了和普通的值一樣的“頭等公民”,可以像任何其他數(shù)據(jù)類型的值一樣被傳遞和操作函數(shù)式編程成為越來越流行的編程范式大數(shù)據(jù)應(yīng)用和并發(fā)需求的驅(qū)動;純函數(shù)的行為表現(xiàn)出與上下文無關(guān)的透明性和無副作用性,避免了多線程并發(fā)應(yīng)用中最復(fù)雜的狀態(tài)同步問題。Scala在架構(gòu)層面上提倡上層采用面向?qū)ο缶幊?,而底層采用函?shù)式編程。
匿名函數(shù)定義函數(shù)最通用的方法是作為某個類或者對象的成員,這種函數(shù)被稱為方法,其定義的基本語法為:def方法名(參數(shù)列表):結(jié)果類型={方法體}
匿名函數(shù)匿名函數(shù)(函數(shù)字面量):函數(shù)變量的值counter的類型是“(Int)=>Int”,表示具有一個整數(shù)類型參數(shù)并返回一個整數(shù)的函數(shù);“{value=>value+1}”為函數(shù)字面量,作為counter的初始化值,“=>”前面的value是參數(shù)名,“=>”后面是具體的運(yùn)算語句或表達(dá)式,使用類型推斷系統(tǒng),可以省略函數(shù)類型
匿名函數(shù)
占位符語法當(dāng)函
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 塔吊安裝質(zhì)量保證合同
- 幼兒園心理咨詢微信平臺管理
- 2024年信用擔(dān)保連帶責(zé)任合同
- 教育行業(yè)項目經(jīng)理轉(zhuǎn)正工作經(jīng)驗總結(jié)
- 中小學(xué)網(wǎng)上作業(yè)公示制度
- 幼兒園教師線上家長會發(fā)言稿
- 2024北京市車指標(biāo)租賃期間維修服務(wù)合同
- 小學(xué)新生課外閱讀推廣方案
- 2024年度金融科技服務(wù)平臺建設(shè)與運(yùn)營合同
- 2024年度物業(yè)管理分包合同
- 上海市交大附中附屬嘉定德富中學(xué)2024-2025學(xué)年九年級上學(xué)期期中考數(shù)學(xué)卷
- 屠宰場食品安全管理制度
- 部編版(2024秋)語文一年級上冊 6 .影子課件
- 2024秋期國家開放大學(xué)??啤缎淌略V訟法學(xué)》一平臺在線形考(形考任務(wù)一至五)試題及答案
- 基于SICAS模型的區(qū)域農(nóng)產(chǎn)品品牌直播營銷策略研究
- 病例討論英文
- 2024秋期國家開放大學(xué)??啤兑簤号c氣壓傳動》一平臺在線形考(形考任務(wù)+實驗報告)試題及答案
- 【課件】植物體的結(jié)構(gòu)層次課件-2024-2025學(xué)年人教版生物七年級上冊
- 24秋國家開放大學(xué)《0-3歲嬰幼兒的保育與教育》期末大作業(yè)參考答案
- 相對濕度計算公式
- 2024版腫瘤患者靜脈血栓防治指南解讀 課件
評論
0/150
提交評論