版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
語(yǔ)言基礎(chǔ)第1章章節(jié)介紹
本章內(nèi)容主要介紹了Scala安裝與運(yùn)行方法,掌握Scala的常量和變量的使用方法,以及Scala運(yùn)算符和程序控制結(jié)構(gòu)。學(xué)會(huì)Scala幾種集合類型及其使用方法,掌握Scala的函數(shù)和函數(shù)式編程方法以及類與模式配方法,因?yàn)楸緯腔趦煞N語(yǔ)言:Scala以及Python,所以1.6小節(jié)介紹了Python的匿名函數(shù)、閉包和裝飾器。學(xué)習(xí)目標(biāo):1.掌握Scala常量變量、集合類型2.熟悉Scala函數(shù)和函數(shù)式編程方法3.掌握Python匿名函數(shù)、閉包和裝飾器的使用方法1.1Scala安裝與運(yùn)行1.下載Scala安裝包首先,需要訪問(wèn)Scala的官方網(wǎng)站。在官網(wǎng)上,選擇適合的操作系統(tǒng)(Windows、Mac或Linux)的Scala版本。通常,建議選擇最新穩(wěn)定版。然后,下載安裝包。根據(jù)選擇,點(diǎn)擊相應(yīng)的下載鏈接。對(duì)于Windows系統(tǒng),通常會(huì)提供“.msi”或“.zip”格式的安裝包;對(duì)于Mac和Linux系統(tǒng),則可能會(huì)提供“.tgz”或“.deb”等格式的安裝包。2.安裝Scala(1)Windows系統(tǒng)如果下載的是“.msi”安裝包,直接雙擊運(yùn)行并按照提示進(jìn)行安裝。安裝過(guò)程中,可以選擇安裝路徑并接受許可協(xié)議。如果下載的是“.zip”安裝包,需要將壓縮包解壓到想要的安裝路徑。(2)Mac和Linux系統(tǒng)對(duì)于“.tgz”安裝包,需要使用tar命令進(jìn)行解壓。例如,在Linux上,可以使用命令tar-xvfscala-xxxx.tgz-C/usr/local/將安裝包解壓到/usr/local/目錄。對(duì)于“.deb”安裝包(主要在Debian和Ubuntu系統(tǒng)上),可以使用dpkg或apt命令進(jìn)行安裝。Scala運(yùn)行在Java虛擬機(jī)(JVM)之上,因此只要安裝有相應(yīng)的Java虛擬機(jī)的操作系統(tǒng)都可以運(yùn)行Scala程序,包括Window、Linux、UNIX、MacOS等。下面來(lái)介紹Scala的安裝與配置過(guò)程。在安裝之前,先保證已安裝了JVM。Scala編程環(huán)境配置所示。1.
Windows系統(tǒng)?右鍵點(diǎn)擊“此電腦”或“計(jì)算機(jī)”,選擇“屬性”。點(diǎn)擊“高級(jí)系統(tǒng)設(shè)置”,然后點(diǎn)擊“環(huán)境變量”。在“系統(tǒng)變量”區(qū)域,找到并選擇“Path”變量,然后點(diǎn)擊“編輯”。在“編輯環(huán)境變量”窗口中,點(diǎn)擊“新建”,并添加Scala安裝目錄下的bin文件夾的路徑。例如,如果將Scala安裝在C:\ProgramFiles\Scala\,則需要添加C:\ProgramFiles\Scala\bin。也可以選擇創(chuàng)建一個(gè)新的系統(tǒng)變量(如SCALA_HOME),并將其值設(shè)置為Scala的安裝路徑,然后在Path變量中添加%SCALA_HOME%\bin。2.
Mac和Linux系統(tǒng)??在Linux上,通常需要編輯/etc/profile或~/.bashrc文件,并添加如下行:exportPATH=$PATH:/usr/local/scala/bin(假設(shè)將Scala解壓到了/usr/local/scala/)。在Mac上,可以編輯~/.bash_profile、~/.zshrc或相應(yīng)的shell配置文件,并添加類似的路徑。修改完配置文件后,需要運(yùn)行source命令來(lái)重新加載配置文件,例如source~/.bash_profile。3.
驗(yàn)證安裝?打開(kāi)命令行終端?:在Windows上,可以使用CMD或PowerShell;在Mac和Linux上,可以使用Terminal。?輸入驗(yàn)證命令?:在命令行中輸入scala-version。?檢查輸出?:如果安裝成功,命令行將顯示安裝的Scala版本信息。Scala編程環(huán)境配置所示。4.
ScalaREPL環(huán)境的使用ScalaREPL(Read-Eval-PrintLoop)環(huán)境是一個(gè)強(qiáng)大的交互式編程工具,允許開(kāi)發(fā)者在命令行中即時(shí)輸入、執(zhí)行和查看Scala代碼的結(jié)果。以下是如何使用ScalaREPL環(huán)境進(jìn)行交互式編程的指南。(3)
啟動(dòng)ScalaREPL環(huán)境。Scala安裝完成后,可以通過(guò)以下方式啟動(dòng)ScalaREPL環(huán)境:打開(kāi)命令行工具(如Windows的cmd、PowerShell,或Linux/macOS的終端)。輸入scala命令,并按下回車鍵。此時(shí),應(yīng)該會(huì)看到類似“WelcometoScalaxxx(OpenJDKxxx-BitServerVM,Javaxxx)”的歡迎信息,以及一個(gè)提示符(如scala>),表示已經(jīng)成功進(jìn)入了ScalaREPL環(huán)境。在REPL環(huán)境中,用戶可以逐行輸入Scala代碼,并立即看到執(zhí)行結(jié)果。如圖1.2所示。(4) REPL常用命令如下:
退出REPL:輸入:quit或:q退出REPL。
粘貼代碼:使用:paste進(jìn)入粘貼模式,粘貼代碼后按Ctrl+D退出粘貼模式。
查看歷史命令:輸入:history查看之前輸入的命令。041.2Scala語(yǔ)法基礎(chǔ)Scala是一門類Java的多范式語(yǔ)言,它整合了面向?qū)ο缶幊毯秃瘮?shù)式編程的最佳特性。具體來(lái)講:Scala運(yùn)行于Java虛擬機(jī)(JVM)之上,并且兼容現(xiàn)有的Java程序,可以與Java類進(jìn)行互操作,包括調(diào)用Java方法,創(chuàng)建Java對(duì)象,繼承Java類和實(shí)現(xiàn)Java接口。Scala是一門純粹的面向?qū)ο蟮恼Z(yǔ)言。在Scala語(yǔ)言中,每個(gè)值都是對(duì)象,每個(gè)操作都是方法調(diào)用。對(duì)象的數(shù)據(jù)類型以及行為由類和特質(zhì)描述。類抽象機(jī)制的擴(kuò)展有兩種途徑,一種途徑是子類繼承,另一種途徑是靈活的混入(mixin)機(jī)制,這兩種途徑能避免多重繼承的種種問(wèn)題。Scala也是一門函數(shù)式語(yǔ)言。在Scala語(yǔ)言中,每個(gè)函數(shù)都是一個(gè)值,并且和其他類型(如整數(shù)、字符串等)的值處于同一地位。Scala提供了輕量級(jí)的語(yǔ)法用以定義匿名函數(shù),支持高階函數(shù),允許嵌套多層函數(shù),并支持柯里化。1.2.1Scala的常量與變量在Scala中,常量和變量是編程中的基本概念,它用于存儲(chǔ)數(shù)據(jù)。下面詳細(xì)解釋Scala中常量與變量的聲明方式、區(qū)別以及使用示例。1.常量的聲明與使用在Scala中,常量使用val關(guān)鍵字進(jìn)行聲明。一旦為常量賦值后,其值就不能再被改變,這類似于Java中的final變量。例如:valconstantName:DataType=value其中,DataType可以省略,Scala的類型推斷機(jī)制會(huì)根據(jù)value自動(dòng)確定數(shù)據(jù)類型。以下是Scala常量聲明的例子。valpi:Double=3.14valgreeting:String="Hello,Scala!"在上述示例中,pi是一個(gè)雙精度浮點(diǎn)型常量,greeting是一個(gè)字符串常量。由于使用了val關(guān)鍵字,這些常量的值在初始化后就不能再被改變。1.2.1Scala的常量與變量2.變量的聲明與使用變量使用var關(guān)鍵字進(jìn)行聲明,其值在程序的生命周期內(nèi)可以多次改變。例如:varvariableName:DataType=value同樣地,DataType可以省略,Scala會(huì)根據(jù)value自動(dòng)確定數(shù)據(jù)類型。以下是Scala變量聲明的例子。varcounter:Int=0varname:String="Alice"在上述示例中,counter是一個(gè)整型變量,name是一個(gè)字符串變量。由于使用了var關(guān)鍵字,這些變量的值可以在程序的生命周期內(nèi)被多次改變。1.2.1Scala的常量與變量3.
常量與變量的區(qū)別(1)
?不可變性?:常量使用val關(guān)鍵字聲明,一旦賦值就不能再改變;而變量使用var關(guān)鍵字聲明,其值可以多次改變。(2)
?類型推斷?:在Scala中,無(wú)論是常量還是變量,都可以省略數(shù)據(jù)類型聲明,由Scala的類型推斷機(jī)制自動(dòng)確定數(shù)據(jù)類型。(3)
?使用場(chǎng)景?:常量通常用于存儲(chǔ)程序中不會(huì)改變的值,如數(shù)學(xué)常數(shù)、配置參數(shù)等;而變量則用于存儲(chǔ)需要在程序運(yùn)行過(guò)程中改變的值。4.注意事項(xiàng)(1)變量名必須以字母(A-Z或a-z)或下劃線(_)開(kāi)頭,后續(xù)字符可以是字母、數(shù)字(0-9)或下劃線。(2)變量名不能是Scala的關(guān)鍵字。(3)變量名應(yīng)能清晰地表達(dá)其用途或含義,避免使用模糊或無(wú)意義的名稱。(4)盡量避免使用單字符變量名,以提高代碼的可讀性。(5)Scala鼓勵(lì)優(yōu)先使用val(常量),除非確實(shí)需要對(duì)其進(jìn)行修改,才使用var(變量)。1.2.1Scala的常量與變量5.Scala的數(shù)據(jù)類型在Scala中,數(shù)據(jù)類型豐富多樣,包括基本類型、集合類型以及特殊類型等。以下是每種類型的詳細(xì)說(shuō)明:(1)基本類型,如表1.1所示表1.1
Scala數(shù)據(jù)基本類型Byte?8位有符號(hào)整數(shù),取值范圍為-128到127。?Short?16位有符號(hào)整數(shù),取值范圍為-32768到32767。?Int?32位有符號(hào)整數(shù),取值范圍為-2147483648到2147483647。?Long?64位有符號(hào)整數(shù),取值范圍為-9223372036854775808到9223372036854775807。?Float?32位單精度浮點(diǎn)數(shù)。?Double?64位雙精度浮點(diǎn)數(shù)。?Char?16位無(wú)符號(hào)Unicode字符,取值范圍為U+0000到U+FFFF。?String?表示字符序列。?Boolean?表示真(true)或假(false)。?Unit?表示無(wú)值,相當(dāng)于Java中的void。1.2.1Scala的常量與變量5.Scala的數(shù)據(jù)類型在Scala中,數(shù)據(jù)類型豐富多樣,包括基本類型、集合類型以及特殊類型等。以下是每種類型的詳細(xì)說(shuō)明:
表1.2
Scala數(shù)據(jù)集合類型List?不可變鏈表。?Set?不可變集合。?Map?不可變鍵值對(duì)集合。?Array?可變數(shù)組。?Tuple?包含不同類型元素的不可變?nèi)萜鳌?Option?代表有可能含有值或?yàn)榭盏娜萜鳌?Either?表示兩種可能的值類型之一。?Try?處理操作結(jié)果可能成功或失敗的容器。
1.2.1Scala的常量與變量5.Scala的數(shù)據(jù)類型在Scala中,數(shù)據(jù)類型豐富多樣,包括基本類型、集合類型以及特殊類型等。以下是每種類型的詳細(xì)說(shuō)明:
表1.3
Scala數(shù)據(jù)特殊類型Nothing?表示無(wú)返回值類型,是所有類型的子類型。?Any?所有類型的超類型。?AnyRef?所有引用類型的超類。?Null?表示所有引用類型的空值。1.2.1Scala的常量與變量
Scala數(shù)據(jù)類型的層次結(jié)構(gòu)以Any為根,所有類型都繼承自它。其中,AnyVal表示值類型,包括如Int、Double等不可變的直接存儲(chǔ)值的類型;而AnyRef則代表引用類型,除了值類型外的所有類型都繼承自它,提供了對(duì)JVM中對(duì)象引用的支持。此外,Null是AnyRef的子類型,表示空引用,而Nothing則是所有類型的子類型,常用于表示不會(huì)正常返回的方法的返回類型。圖1.3展示了Scala數(shù)據(jù)類型的層次結(jié)構(gòu)。在這幅圖中,虛線箭頭代表視圖轉(zhuǎn)換(viewbounds)。視圖轉(zhuǎn)換是Scala中的一種機(jī)制,它允許一個(gè)類型的值在某些上下文中被隱式地轉(zhuǎn)換為另一個(gè)類型。這種轉(zhuǎn)換通常由編譯器自動(dòng)應(yīng)用,以便使代碼更加靈活和通用。從Scala2.13開(kāi)始,很多情況下視圖邊界和隱式轉(zhuǎn)換已經(jīng)被移除或替換為更明確的特性,例如擴(kuò)展方法。由于本書并非Scala語(yǔ)言教材。因此,此處讀者可以先將虛線箭頭粗略地理解為類型A可以沿著箭頭方向隱式轉(zhuǎn)換到類型B。如需對(duì)視圖轉(zhuǎn)換作進(jìn)一步了解,請(qǐng)參看其他Scala語(yǔ)言相關(guān)書籍。此處不再贅述。1.2.2Scala運(yùn)算符和程序控制結(jié)構(gòu)
1.
運(yùn)算符一個(gè)運(yùn)算符即是一個(gè)符號(hào),用于告訴編譯器來(lái)執(zhí)行指定的數(shù)學(xué)運(yùn)算和邏輯運(yùn)算。Scala含有豐富的內(nèi)置運(yùn)算符,包括數(shù)學(xué)運(yùn)算符(加(+)、減(-)、乘(*)、除(/)、余數(shù)(%));關(guān)系運(yùn)算符(大于(>)、小于(<)、等于(==)、不等于(!=)、大于等于(>=)、小于等于(<=));邏輯運(yùn)算符(邏輯與(&&)、邏輯或(||)、邏輯非(!));位運(yùn)算符(?按位與(&)、按位或(|)、按位異或(^)、按位取反(~)等)以及賦值運(yùn)算符(=)。操作符優(yōu)先級(jí):算術(shù)運(yùn)算符
>關(guān)系運(yùn)算符>邏輯運(yùn)算符>賦值運(yùn)算符。Scala在使用運(yùn)算符時(shí),是以運(yùn)算符的形式進(jìn)行方法的調(diào)用,即運(yùn)算符的重載。因此,Scala運(yùn)算符有以下注意事項(xiàng):(1)a+b等價(jià)于a+(b)。(2)scala中沒(méi)有++、--,但是可以用+=、-=代替。(3)運(yùn)算符都是方法的重載,都是方法的調(diào)用。1.2.2Scala運(yùn)算符和程序控制結(jié)構(gòu)
1.
程序控制結(jié)構(gòu)(1)
條件語(yǔ)句。?用于根據(jù)條件執(zhí)行不同的代碼塊,如if語(yǔ)句、if-else語(yǔ)句、if-elseif-else語(yǔ)句。條件語(yǔ)句實(shí)例代碼如下:valnumber=10if(number>5){println("Numberisgreaterthan5")}else{println("Numberis5orless")}1.2.2Scala運(yùn)算符和程序控制結(jié)構(gòu)以下是for循環(huán)的示例代碼:1.
程序控制結(jié)構(gòu)(2)循環(huán)語(yǔ)句。?用于重復(fù)執(zhí)行代碼塊,如while循環(huán)和for循環(huán)。以下是while循環(huán)的實(shí)例代碼:vari=0while(i<5){println(i)i+=1}for(k<-1to5){
println(k)}1.2.2Scala運(yùn)算符和程序控制結(jié)構(gòu)
符號(hào)“<-”通常用于for循環(huán)中,表示對(duì)一個(gè)值的范圍或集合進(jìn)行遍歷。在for循環(huán)中,“<-”符號(hào)可以用于表示一個(gè)值的范圍,通常與to或until方法一起使用。to方法包含結(jié)束值,而until方法不包含結(jié)束值?!?lt;-”符號(hào)還可以用于遍歷集合,如數(shù)組、列表、集合(Set)、映射(Map)等。這種用法類似Python中in的作用。
以下的例子說(shuō)明運(yùn)算符和程序控制結(jié)構(gòu)的使用方法。該程序?qū)崿F(xiàn)計(jì)算1到10之間所有偶數(shù)的和,代碼如下:objectEvenSum{defmain(args:Array[String]):Unit={//初始化變量sum為0,用于存儲(chǔ)偶數(shù)的和varsum:Int=0//使用for循環(huán)遍歷1到10之間的所有數(shù)字for(i<-1to10){//使用關(guān)系運(yùn)算符判斷當(dāng)前數(shù)字是否為偶數(shù)if(i%2==0){//如果是偶數(shù),則使用算術(shù)運(yùn)算符將其加到sum中sum+=i}//輸出偶數(shù)的和println(s"Thesumofevennumbersbetween1and10is:$sum")}}1.3Scala集合類型集合三大類:序列Seq、集合Set、映射Map。所有集合都擴(kuò)展自Iterable特質(zhì),如圖1.4所示。對(duì)于幾乎所有的集合類,Scala都同時(shí)提供了可變和不可變的版本,分別位于以下兩個(gè)包:不可變集合:scala.collection.immutable可變集合:scala.collection.mutable。Scala不可變集合,就是指該集合對(duì)象不可修改,每次修改就會(huì)返回一個(gè)新對(duì)象,而不會(huì)對(duì)原對(duì)象進(jìn)行修改,類似于java中的String對(duì)象;可變集合,就是這個(gè)集合可以直接對(duì)原對(duì)象進(jìn)行修改,而不會(huì)返回新的對(duì)象,類似于java中的StringBuilder對(duì)象。這兩個(gè)包的層次結(jié)構(gòu)如圖1.5和圖1.6所示。圖1.4圖1.5圖1.61.3.1數(shù)組數(shù)組是一種可變的、可索引的、元素具有相同類型的數(shù)據(jù)集合。Scala提供了參數(shù)化類型的通用數(shù)組類Array[T],其中T可以是任意的Scala類型,可以通過(guò)顯式指定類型或者通過(guò)隱式推斷來(lái)實(shí)例化一個(gè)數(shù)組。1.
定長(zhǎng)數(shù)組定長(zhǎng)數(shù)組是指在創(chuàng)建時(shí)指定了大小,并且之后不能改變的數(shù)組。在Scala中,定長(zhǎng)數(shù)組是通過(guò)Array類或newArray[T](size)構(gòu)造函數(shù)來(lái)創(chuàng)建的。由于數(shù)組在內(nèi)存中是連續(xù)存儲(chǔ)的,因此定長(zhǎng)數(shù)組在訪問(wèn)元素時(shí)具有非常高的性能。定長(zhǎng)數(shù)組的創(chuàng)建有兩種方式:(1)
使用Array類的apply方法,代碼如下:valfixedArray=Array(1,2,3,4,5)//創(chuàng)建一個(gè)包含5個(gè)整數(shù)的定長(zhǎng)數(shù)組(2)
使用new關(guān)鍵字和Array類的構(gòu)造函數(shù),代碼如下:valfixedArray2=newArray[Int](5)//創(chuàng)建一個(gè)長(zhǎng)度為5的整數(shù)定長(zhǎng)數(shù)組,初始值為0fixedArray2(0)=10//設(shè)置第一個(gè)元素為101.3.1數(shù)組以下例子演示了Scala定長(zhǎng)數(shù)組的使用方法。讀者可以在自己所習(xí)慣的IDE中編寫代碼,后面章節(jié)相同。在一個(gè)新建的項(xiàng)目的src下新建arraytest包,包下新建ArrayDemo對(duì)象。運(yùn)行結(jié)果如圖1.7所示。圖1.71.3.1數(shù)組不定長(zhǎng)數(shù)組(也稱為可變數(shù)組)是指可以在創(chuàng)建后動(dòng)態(tài)地添加和刪除元素的數(shù)組。在Scala中,不定長(zhǎng)數(shù)組通常是通過(guò)ArrayBuffer或ListBuffer等可變集合來(lái)實(shí)現(xiàn)的。雖然它們不是嚴(yán)格意義上的數(shù)組,但提供了類似數(shù)組的功能,并且具有更高的靈活性。不定長(zhǎng)數(shù)組的創(chuàng)建有兩種方式:(1)
使用ArrayBuffer,例如:importscala.collection.mutable.ArrayBuffervalmutableArray=ArrayBuffer[Int]()//創(chuàng)建一個(gè)空的可變整數(shù)數(shù)組mutableArray+=1//添加元素1mutableArray+=(2,3,4,5)//批量添加元素2,3,4,5(2)
使用ListBuffer雖然ListBuffer看起來(lái)更像是一個(gè)鏈表,它是一個(gè)變長(zhǎng)列表(可變列表)。但是,由于它可以使用索引更新元素,以及具備數(shù)組的各種操作性質(zhì)。因此,這里把它看作是一種不定長(zhǎng)數(shù)組。但它使用的例子,仍然在列表部分展示。以下是它創(chuàng)建的方法:importscala.collection.mutable.ListBuffervallistBuffer=ListBuffer[Int]()//創(chuàng)建一個(gè)空的可變整數(shù)列表listBuffer.append(1)//添加元素1listBuffer.appendAll(List(2,3,4,5))//批量添加元素2,3,4,51.3.1數(shù)組3.數(shù)組轉(zhuǎn)換在Scala中,yield關(guān)鍵字通常與for循環(huán)結(jié)合使用,用于從循環(huán)中生成一個(gè)新的集合。這個(gè)新集合包含for循環(huán)體中每次迭代通過(guò)yield關(guān)鍵字產(chǎn)生的值。在數(shù)組轉(zhuǎn)換中,yield關(guān)鍵字非常有用,因?yàn)樗试S對(duì)數(shù)組中的元素進(jìn)行轉(zhuǎn)換,并收集轉(zhuǎn)換后的結(jié)果到一個(gè)新的數(shù)組中。當(dāng)只想轉(zhuǎn)換數(shù)組中的某些元素時(shí),yield關(guān)鍵字還可以在for循環(huán)中使用if守衛(wèi)來(lái)過(guò)濾出需要轉(zhuǎn)換的元素。1.3.2元祖元組可以裝著多個(gè)不同類型的值,是不同類型的值的聚集。元組使用小括號(hào)將多個(gè)元素括起來(lái),元素之間用逗號(hào)分隔,元素的類型和個(gè)數(shù)任意。1.創(chuàng)建元組創(chuàng)建元組有兩種形式,直接創(chuàng)建和參數(shù)形式創(chuàng)建:valt=("hadoop","spark",11)//直接創(chuàng)建valt1,(a,b,c)=("hadoop","spark",11)//參數(shù)形式創(chuàng)建參數(shù)形式運(yùn)行結(jié)果如圖1.10所示??梢允褂孟聞澗€加下標(biāo)的形式訪問(wèn)元組,例如_1,_2等方式訪問(wèn)元組。這里要注意的是,元組的下標(biāo)是從1開(kāi)始而非0,區(qū)別數(shù)組從0開(kāi)始。1.3.2元祖2.訪問(wèn)元組可以使用下劃線加下標(biāo)的形式訪問(wèn)元組,例如_1,_2等方式訪問(wèn)元組。這里要注意的是,元組的下標(biāo)是從1開(kāi)始而非0,區(qū)別數(shù)組從0開(kāi)始。訪問(wèn)元組實(shí)例代碼如下:valt1=t._1valt_a=t._23.元組類型元組的實(shí)際類型取決于它的元素的類型,比如:(99,"runoob")是Tuple2[Int,String]。('u','r',"the",1,4,"me")為Tuple6[Char,Char,String,Int,Int,String]。目前Scala支持的元組最大長(zhǎng)度為22。對(duì)于更大長(zhǎng)度可以使用集合,或者擴(kuò)展元組。1.3.2元祖4.遍歷元組可以通過(guò)以下方式對(duì)元組進(jìn)行迭代表遍歷。通過(guò)調(diào)用迭代器以及foreach函數(shù),找到元組中的值。valt=(4,3,2,1)//遍歷t的productIterator,并打印每個(gè)元素的值。ductIterator是對(duì)象t的字段迭代器。ductIterator.foreach{i=>println("value="+i)}1.3.2元祖4.遍歷元組可以通過(guò)以下方式對(duì)元組進(jìn)行迭代表遍歷。通過(guò)調(diào)用迭代器以及foreach函數(shù),找到元組中的值。defmain(args:Array[String]):Unit={//聲明元組的方式:(元素1,元素2,元素3)valtuple:(Int,String,Boolean)=(10,"hello",true)//訪問(wèn)元組,調(diào)用方式:_順序號(hào)//注意:順序號(hào)從1開(kāi)始println(tuple._2)//hello1.3.2元祖4.遍歷元組可以通過(guò)以下方式對(duì)元組進(jìn)行迭代表遍歷。通過(guò)調(diào)用迭代器以及foreach函數(shù),找到元組中的值。//通過(guò)索引訪問(wèn)元素//注意:索引從0開(kāi)始println(ductElement(0))//通過(guò)迭代器訪問(wèn)數(shù)據(jù)for(x<-ductIterator){println(x)}}1.3.2元祖1.
拉鏈操作拉鏈操作即使用zip方法把元組的多個(gè)值綁定在一起。寫法也是有如下例的兩種。valnames=Array("tom","jerry")valscores=Array(90,80)names.zip(scores)nameszipscores拉鏈操作的運(yùn)行代碼如圖1.12所示
圖1.12
拉鏈操作1.3.2元祖6.
數(shù)據(jù)丟失如果兩個(gè)數(shù)組的元素個(gè)數(shù)不一致,拉鏈操作后生成的數(shù)組的長(zhǎng)度為較小的那個(gè)數(shù)組的元素個(gè)數(shù),從而造成數(shù)據(jù)丟失。valarr1=Array(1,2)valarr2=Array("x","y","z")arr1ziparr2那數(shù)據(jù)“z”就被丟失了。1.3.3集合ScalaSet(集合)是沒(méi)有重復(fù)的對(duì)象集合,所有的元素都是唯一的。Scala集合分為可變的和不可變的集合。默認(rèn)情況下,Scala使用的是不可變集合,如果想使用可變集合,需要引用scala.collection.mutable.Set包。1.不可變Setset是不重復(fù)元素的集合。在下面例子中,展示了如何創(chuàng)建一個(gè)不可變的Set,添加元素,檢查元素是否存在以及移除元素。需要注意的是,由于Scala的集合是不可變的,每次操作都會(huì)返回一個(gè)新的集合實(shí)例。packageaggregatedefmain(args:Array[String]):Unit={//創(chuàng)建一個(gè)空的不可變SetvalemptySet:Set[Int]=Set()//使用apply方法創(chuàng)建一個(gè)包含元素的不可變Setvalnumbers:Set[Int]=Set(1,2,3,4,5)//添加元素到Set(由于是不可變的,會(huì)返回一個(gè)新的Set)valnewNumbers=numbers+6//打印Set的內(nèi)容
1.3.3集合println("OriginalSet:"+numbers)//輸出:OriginalSet:Set(5,1,2,3,4)println("NewSetafteraddingelement:"+newNumbers)//輸出:NewSetafteraddingelement:Set(5,1,2,3,4,6)//檢查元素是否存在于Set中println("Doesthesetcontain3?"+numbers.contains(3))//輸出:Doesthesetcontain3?trueprintln("Doesthesetcontain6?"+numbers.contains(6))//輸出:Doesthesetcontain6?false//移除元素(同樣返回一個(gè)新的Set)valremovedNumber=numbers-4println("Setafterremovingelement:"+removedNumber)//輸出:Setafterremovingelement:Set(5,1,2,3)}}1.3.3集合圖1.13不可變Set的使用運(yùn)行結(jié)果如圖1.13所示。1.3.3集合2.可變Set以下的例子中,展示了如何創(chuàng)建一個(gè)可變的Set,添加單個(gè)或多個(gè)元素,檢查元素是否存在以及移除單個(gè)或多個(gè)元素。由于可變Set的特性,操作會(huì)直接修改原Set實(shí)例。packageaggregate//導(dǎo)入可變Setimportscala.collection.mutable.SetobjectMutableSetExample{defmain(args:Array[String]):Unit={//創(chuàng)建一個(gè)空的可變SetvalemptySet:Set[Int]=Set()
1.3.3集合//使用+=方法添加元素到SetemptySet+=1emptySet+=2emptySet+=3emptySet+=4emptySet+=5//打印Set的內(nèi)容println("InitialSet:"+emptySet)//輸出:InitialSet:Set(5,1,2,3,4)//添加多個(gè)元素
1.3.3集合emptySet++=List(6,7,8)println("Setafteraddingmultipleelements:"+emptySet)//輸出:Setafteraddingmultipleelements:Set(5,1,2,3,4,6,7,8)//檢查元素是否存在于Set中println("Doesthesetcontain3?"+emptySet.contains(3))//輸出:Doesthesetcontain3?trueprintln("Doesthesetcontain9?"+emptySet.contains(9))//輸出:Doesthesetcontain9?false//移除元素1.3.3集合emptySet-=4println("Setafterremovingelement:"+emptySet)//輸出:Setafterremovingelement:Set(5,1,2,3,6,7,8)//移除多個(gè)元素emptySet--=List(1,2)println("Setafterremovingmultipleelements:"+emptySet)//輸出:Setafterremovingmultipleelements:Set(5,3,6,7,8)}}1.3.3集合運(yùn)行結(jié)果如圖1.14所示??傊?,不可變的集合在添加元素的時(shí)候,原來(lái)的集合不變,生成一個(gè)新的集合來(lái)保存原來(lái)的添加的元素;可變的集合在添加元素的時(shí)候,并不會(huì)新生成一個(gè)集合,而是直接將元素添加到原來(lái)的集合中。1.3.4列表Scala列表類似于數(shù)組,它所有元素的類型都相同,但是它也有所不同:列表默認(rèn)是不可變的,值一旦被定義了就不能改變,其次列表具有遞歸的結(jié)構(gòu)(也就是鏈接表結(jié)構(gòu))而數(shù)組不是。1.不可變列表以下Scala代碼展示了如何操作不可變列表。具體步驟是:創(chuàng)建一個(gè)不可變列表list1;將0插入到list1的前面,生成新的列表list2、list3和list4;將4添加到list1的后面,生成新的列表list6;創(chuàng)建另一個(gè)不可變列表list0;將list1和list0合并,生成新的列表list7和list8;最后將list0插入到list1的前面,生成新的列表list9并打印。1.3.4列表packageaggregateobjectImmutListDemo{defmain(args:Array[String]):Unit={//創(chuàng)建一個(gè)不可變集合vallist1=List(1,2,3)//把0插入到list1的前面生成一個(gè)新的Listvallist2=0::list1vallist3=list1.::(0)vallist4=0+:list11.3.4列表vallist5=list1.+:(0)//把一個(gè)元素添加到list1的后面產(chǎn)生一個(gè)新集合vallist6=list1:+4vallist0=List(4,5,6)//把2個(gè)list合并生成一個(gè)新的listvallist7=list1++list0vallist8=list1++:list0//把list0插入到list1前面生成一個(gè)新的集合vallist9=list1.:::(list0)println(list9)}}1.3.4列表運(yùn)行結(jié)果如圖1.15所示。圖1.15不可變列表運(yùn)行結(jié)果1.3.4列表1.
可變列表在Scala中,可變列表是一種可以動(dòng)態(tài)修改的數(shù)據(jù)結(jié)構(gòu),提供了添加、刪除和修改元素的能力。這提供了更大的靈活性,但同時(shí)也犧牲了不可變列表的一些優(yōu)勢(shì),如線程安全性。可變列表適合用于需要頻繁修改的場(chǎng)景,但是在多線程環(huán)境中需要謹(jǐn)慎使用,以避免并發(fā)問(wèn)題。在Scala中,可變列表是scala.collection.mutable.ListBuffer。在使用前需要先引入這個(gè)類。以下Scala代碼的功能是演示如何使用ListBuffer進(jìn)行列表操作。具體步驟是:創(chuàng)建一個(gè)初始包含1,2,3的ListBufferlist0;創(chuàng)建一個(gè)空的ListBufferlist1,并添加元素4和5;將list0和list1合并為新的ListBufferlist2;最后,在list0的末尾添加元素5,生成新的ListBufferlist3;打印list3的內(nèi)容。packageaggregateimportscala.collection.mutable.ListBufferobjectMutListDemo{defmain(args:Array[String]):Unit={vallist0=ListBuffer[Int](1,2,3)vallist1=newListBuffer[Int]()list1+=4list1.append(5)vallist2=list0++list1vallist3=list0:+5println(list3)}}1.3.5映射Scala中的映射(Map)是一種鍵值對(duì)的數(shù)據(jù)結(jié)構(gòu),類似于其他編程語(yǔ)言中的字典或哈希表。在Scala中,映射主要有兩種實(shí)現(xiàn):不可變的HashMap(scala.collection.immutable.HashMap)和可變的HashMap(scala.collection.mutable.HashMap)。映射中的鍵是唯一的,而值則可以重復(fù)。構(gòu)建映射(1).直接構(gòu)建valscores=Map("A"->90,"B"->80)定義Map時(shí),需要為鍵值對(duì)定義類型。如果需要添加key-value對(duì),可以使用+號(hào),例如:A+=('I'->1)A+=('J'->5)A+=('K'->10)A+=('L'->100)(2).通過(guò)元組構(gòu)建valscores=Map(("A",90),("B",80))(3).構(gòu)建可變映射valscores=scala.collection.mutbale.Map("A"->90,"B"->80)1.3.5映射2.基本操作例如,已創(chuàng)建了一個(gè)映射:valcolors=Map("red"->"#EF4444","blue"->"#1A237E")。可以對(duì)這一映射進(jìn)行的基本操作。操作作用使用get方法獲取值colors.get("red")返回Some("#EF4444")apply方法(簡(jiǎn)寫為())獲取值colors("red")直接返回#EF4444contains方法檢查鍵是否存在colors.contains("red")返回true對(duì)于可變映射,使用+=操作添加鍵值對(duì)colors+=("green"->"#11AA22")更新現(xiàn)有鍵的值更新鍵值對(duì)colors("red")="#EF4444"對(duì)于可變映射,使用-=操作刪除鍵值對(duì)colors-="red"遍歷所有鍵值對(duì)遍歷映射for((k,v)<-colors)println(s"$k:$v")只遍歷鍵或值遍歷映射for(k<-colors.keys)println(k)或for(v<-colors.values)println(v)表1.5映射的基本操作1.3.5映射3.映射的使用示例以下代碼的功能是演示如何使用可變映射進(jìn)行各種操作,包括添加、修改、刪除鍵值對(duì),以及遍歷映射。(1).初始化映射:創(chuàng)建一個(gè)可變映射scores,并初始化一些鍵值對(duì)。(2).修改值:將鍵"wangwu"的值從70修改為100。(3).打印當(dāng)前映射:將當(dāng)前映射轉(zhuǎn)換為緩沖區(qū)并打印。(4).添加新鍵值對(duì):添加鍵值對(duì)"zhaoliu"->50和"A"->60,"B"->66。(5).刪除鍵值對(duì):刪除鍵"zhangsan"對(duì)應(yīng)的鍵值對(duì)。(6).遍歷鍵集:獲取映射的鍵集并逐個(gè)打印。(7).遍歷鍵值對(duì):遍歷映射的所有鍵值對(duì)并打印。packagemappedtestobjectMappingDemo{defmain(args:Array[String]){valscores=scala.collection.mutable.Map("zhangsan"->90,"lisi"->80,"wangwu"->70)scores("wangwu")=100println(scores.toBuffer)scores("zhaoliu")=50println(scores.toBuffer)scores+=("A"->60,"B"->66)println(scores.toBuffer)scores-="zhangsan"println(scores.toBuffer)valres=scores.keySetfor(elem<-res)println(elem+"")println()for((k,v)<-scores)print(k+":"+v+"")}}運(yùn)行結(jié)果如圖1.17所示。圖1.17映射示例運(yùn)行結(jié)果1.4Scala函數(shù)和函數(shù)式編程Scala有方法與函數(shù),二者在語(yǔ)義上的區(qū)別很小。Scala方法是類的一部分,而函數(shù)是一個(gè)對(duì)象可以賦值給一個(gè)變量。換句話來(lái)說(shuō)在類中定義的函數(shù)即是方法。下面來(lái)介紹Scala的定義和調(diào)用方法。1.4.1Scala函數(shù)定義和調(diào)用Scala作為一種強(qiáng)大的靜態(tài)類型編程語(yǔ)言,不僅支持面向?qū)ο缶幊?,還完美融合了函數(shù)式編程的特性。在Scala中,函數(shù)是一段可以被重復(fù)調(diào)用的代碼塊,它接受輸入?yún)?shù)并返回結(jié)果。函數(shù)使得代碼更加模塊化和可重用。函數(shù)的定義在Scala中,函數(shù)可以通過(guò)def關(guān)鍵字進(jìn)行定義。函數(shù)的定義包括函數(shù)名、參數(shù)列表、返回值類型以及函數(shù)體。例如:defadd(a:Int,b:Int):Int={a+b}在這個(gè)例子中,add是一個(gè)接受兩個(gè)整數(shù)參數(shù)并返回它之和的函數(shù)。需要注意的是,Scala允許省略函數(shù)體的花括號(hào){}和return關(guān)鍵字,如果函數(shù)體只有一個(gè)表達(dá)式,則可以直接將該表達(dá)式作為函數(shù)的返回值。1.4.1Scala函數(shù)定義和調(diào)用2.函數(shù)的調(diào)用定義函數(shù)后,可以通過(guò)函數(shù)名和參數(shù)列表來(lái)調(diào)用它。例如:valresult=add(3,4)println(result)//輸出7在Scala中,調(diào)用函數(shù)時(shí)不需要指定參數(shù)的類型,因?yàn)榫幾g器會(huì)根據(jù)上下文自動(dòng)推斷。3.函數(shù)參數(shù)傳遞方式在Scala中,函數(shù)參數(shù)的傳遞方式主要有兩種:傳值調(diào)用(Call-by-Value)和傳名調(diào)用(Call-by-Name)。(1).傳值調(diào)用。傳值調(diào)用是指在函數(shù)調(diào)用時(shí),首先計(jì)算參數(shù)表達(dá)式的值,然后將這個(gè)值傳遞給函數(shù)內(nèi)部。在函數(shù)內(nèi)部,參數(shù)的值是不可變的,即函數(shù)不能修改傳遞進(jìn)來(lái)的參數(shù)值(除非參數(shù)是可變的數(shù)據(jù)結(jié)構(gòu),如可變數(shù)組或可變對(duì)象)。傳值調(diào)用的實(shí)例代碼如下:defaddByValue(a:Int,b:Int):Int=a+bvalresult=addByValue(2,3+1)//先計(jì)算3+1得到4,然后調(diào)用addByValue(2,4)1.4.1Scala函數(shù)定義和調(diào)用(2).傳名調(diào)用。傳名調(diào)用是指在函數(shù)調(diào)用時(shí),將未計(jì)算的參數(shù)表達(dá)式直接傳遞給函數(shù)內(nèi)部。在函數(shù)內(nèi)部,每次使用這個(gè)參數(shù)時(shí),都會(huì)重新計(jì)算參數(shù)表達(dá)式的值。這種方式允許函數(shù)在多次使用參數(shù)時(shí)獲得不同的值,從而實(shí)現(xiàn)了某種程度的“延遲計(jì)算”。defaddByName(a:Int,b:=>Int):Int=a+bvalresult=addByName(2,{valx=3;x+1})//調(diào)用addByName(2,{valx=3;x+1})在這個(gè)例子中,{valx=3;x+1}是一個(gè)代碼塊,它定義了一個(gè)局部變量x并返回x+1的值。在addByName函數(shù)內(nèi)部,每次使用b時(shí),都會(huì)重新執(zhí)行這個(gè)代碼塊。需要注意的是,傳名調(diào)用在Scala中使用=>符號(hào)來(lái)表示。此外,由于傳名調(diào)用可能會(huì)導(dǎo)致多次計(jì)算參數(shù)表達(dá)式的值,因此在使用時(shí)需要謹(jǐn)慎,以避免不必要的性能開(kāi)銷。(3).無(wú)參函數(shù)無(wú)參函數(shù)是指不接受任何參數(shù)的函數(shù)。在Scala中,無(wú)參函數(shù)可以使用()來(lái)表示空參數(shù)列表。無(wú)參函數(shù)通常用于執(zhí)行某些操作而不需要輸入?yún)?shù)的情況。defgreet():Unit=println("Hello,World!")greet()//輸出Hello,World!在這個(gè)例子中,greet是一個(gè)無(wú)參函數(shù),它不接受任何參數(shù)并打印一條消息。1.4.1Scala函數(shù)定義和調(diào)用4.函數(shù)返回值處理在Scala中,處理函數(shù)返回值的方式有多種,主要包括隱式返回值、使用return關(guān)鍵字,以及使用Option類型來(lái)處理可能的空值情況。defadd(a:Int,b:Int):Int={a+b//隱式返回值}在這個(gè)例子中,add函數(shù)的返回值是a+b的結(jié)果,而無(wú)需顯式地使用return關(guān)鍵字。defmultiply(a:Int,b:Int):Int={returna*b//顯式返回值}然而,需要注意的是,過(guò)度使用return關(guān)鍵字可能會(huì)使代碼變得難以理解和維護(hù)。因此,在Scala中,通常建議盡量使用隱式返回值的方式。(1).隱式返回值在Scala中,函數(shù)的返回值通常是隱式的,即函數(shù)的最后一個(gè)表達(dá)式的值會(huì)自動(dòng)成為函數(shù)的返回值。這種方式符合函數(shù)式編程的風(fēng)格,使得代碼更加簡(jiǎn)潔和易讀。(2).使用return關(guān)鍵字盡管在Scala中不鼓勵(lì)使用return關(guān)鍵字來(lái)返回函數(shù)的值,但在某些情況下,它仍然是可用的。使用return關(guān)鍵字可以顯式地從函數(shù)中返回一個(gè)值,并立即結(jié)束函數(shù)的執(zhí)行。1.4.1Scala函數(shù)定義和調(diào)用(3).使用Option類型處理可能的空值情況在Scala中,Option是一個(gè)容器類型,它可以表示一個(gè)可能存在或可能不存在的值。通過(guò)使用Option類型,可以更好地處理可能的空值情況,從而使代碼更加健壯和可靠。defdivide(a:Int,b:Int):Option[Int]={if(b!=0){Some(a/b)//如果除數(shù)不為0,返回Some(結(jié)果)}else{None//否則返回None}}在這個(gè)例子中,divide函數(shù)返回一個(gè)Option[Int]類型的值。如果除數(shù)b不為0,則函數(shù)返回Some(a/b);否則,返回None。通過(guò)這種方式,可以避免在調(diào)用函數(shù)時(shí)直接處理可能的除零異常,從而使代碼更加安全和易于維護(hù)。1.4.2Scala高級(jí)函數(shù)在Scala中,函數(shù)被認(rèn)為是“頭等公民”,這意味著函數(shù)可以像其他數(shù)據(jù)類型一樣被傳遞和操作?。具體來(lái)說(shuō),函數(shù)在Scala中具有以下特性:(1).?賦值給變量?:可以將函數(shù)賦值給變量,例如valfun=scala.math.ceil。(2).作為參數(shù)傳遞?:函數(shù)可以作為參數(shù)傳遞給其他函數(shù)。(3).?作為返回值?:函數(shù)可以作為其他函數(shù)的返回值?。(4).?匿名函數(shù)?:Scala支持匿名函數(shù)(也稱為lambda表達(dá)式),這些函數(shù)沒(méi)有名字,但可以直接作為參數(shù)傳遞或賦值給變量?。這些特性使得函數(shù)在Scala中非常靈活和強(qiáng)大,能夠廣泛應(yīng)用于各種編程場(chǎng)景中。匿名函數(shù)匿名函數(shù)是指沒(méi)有名稱的函數(shù),通常用于將簡(jiǎn)短的函數(shù)作為參數(shù)傳遞給高階函數(shù)。匿名函數(shù)使用箭頭=>來(lái)分隔參數(shù)列表和函數(shù)體。(1).匿名函數(shù)的定義匿名函數(shù)的定義非常簡(jiǎn)單,它由一個(gè)或多個(gè)參數(shù)、一個(gè)箭頭=>和一個(gè)函數(shù)體組成。例如:valsquare=(x:Int)=>x*x在這個(gè)例子中,square是一個(gè)匿名函數(shù),它接受一個(gè)整數(shù)x作為參數(shù),并返回x的平方值。1.4.2Scala高級(jí)函數(shù)(2).匿名函數(shù)的用法匿名函數(shù)在Scala中的用法非常廣泛,常見(jiàn)的用法包括將匿名函數(shù)作為參數(shù)傳遞給高階函數(shù)。例如,可以將匿名函數(shù)傳遞給map、filter和reduce等高階函數(shù)來(lái)對(duì)集合進(jìn)行操作。將匿名函數(shù)傳遞給map函數(shù)?:valnumbers=List(1,2,3,4)valsquaredNumbers=numbers.map(x=>x*x)//調(diào)用map函數(shù),并傳遞匿名函數(shù)作為參數(shù)//squaredNumbers的值為L(zhǎng)ist(1,4,9,16)b)將匿名函數(shù)傳遞給filter函數(shù)?:valnumbers=List(1,2,3,4,5)valevenNumbers=numbers.filter(x=>x%2==0)//調(diào)用filter函數(shù),并傳遞匿名函數(shù)作為參數(shù)//evenNumbers的值為L(zhǎng)ist(2,4)c)將匿名函數(shù)傳遞給reduce函數(shù)?:valnumbers=List(1,2,3,4,5)valsum=numbers.reduce((x,y)=>x+y)//調(diào)用reduce函數(shù),并傳遞匿名函數(shù)作為參數(shù)//sum的值為151.4.2Scala高級(jí)函數(shù)2.高階函數(shù)在Scala中,高階函數(shù)是指那些可以接受函數(shù)作為參數(shù)或返回函數(shù)作為結(jié)果的函數(shù)。高階函數(shù)是函數(shù)式編程中的一個(gè)重要概念,它允許將函數(shù)作為一等公民進(jìn)行傳遞和操作,從而實(shí)現(xiàn)了更加靈活和強(qiáng)大的代碼復(fù)用和模塊化。(2).高階函數(shù)的用法高階函數(shù)在Scala中的用法非常廣泛,常見(jiàn)的用法包括將函數(shù)作為參數(shù)傳遞給高階函數(shù),以及從高階函數(shù)返回函數(shù)。將函數(shù)作為參數(shù)傳遞?:可以將定義好的函數(shù)作為參數(shù)傳遞給高階函數(shù)。例如:valsquare=(x:Int)=>x*xvalresult=applyFunction(square,3)//調(diào)用applyFunction(square,3),輸出9在這個(gè)例子中,將一個(gè)匿名函數(shù)square作為參數(shù)傳遞給了applyFunction函數(shù),并得到了結(jié)果9。(1).高階函數(shù)的定義高階函數(shù)的定義很簡(jiǎn)單,就是一個(gè)參數(shù)類型為函數(shù)類型或者返回類型為函數(shù)類型的函數(shù)。1.4.2Scala高級(jí)函數(shù)b).從高階函數(shù)返回函數(shù)?:defcreateMultiplier(factor:Int):Int=>Int=(x:Int)=>x*factorvaldouble=createMultiplier(2)valresult=double(5)//調(diào)用double(5),輸出10高階函數(shù)也可以返回函數(shù)作為結(jié)果。例如:在這個(gè)例子中,createMultiplier是一個(gè)高階函數(shù),它接受一個(gè)整數(shù)factor作為參數(shù),并返回一個(gè)函數(shù),該函數(shù)接受一個(gè)整數(shù)x并返回x*factor的結(jié)果。將2作為參數(shù)傳遞給了createMultiplier函數(shù),得到了一個(gè)新的函數(shù)double,然后調(diào)用double(5)得到了結(jié)果10。(3)常見(jiàn)的高階函數(shù)在Scala中,有很多常見(jiàn)的高階函數(shù),如map、filter、reduce等。這些高階函數(shù)通常用于對(duì)集合進(jìn)行操作,并允許將自定義的函數(shù)作為參數(shù)傳遞給它。map?:map函數(shù)用于將一個(gè)函數(shù)應(yīng)用于集合中的每個(gè)元素,并返回一個(gè)新的集合,該集合包含應(yīng)用函數(shù)后的結(jié)果。例如:valnumbers=List(1,2,3,4)valsquaredNumbers=numbers.map(x=>x*x)//調(diào)用map函數(shù),得到List(1,4,9,16)1.4.2Scala高級(jí)函數(shù)b)filter?:filter函數(shù)用于根據(jù)一個(gè)條件函數(shù)過(guò)濾集合中的元素,并返回一個(gè)新的集合,該集合只包含滿足條件的元素。例如:valnumbers=List(1,2,3,4,5)valevenNumbers=numbers.filter(x=>x%2==0)//調(diào)用filter函數(shù),得到List(2,4)c)reduce?:reduce函數(shù)用于將集合中的元素通過(guò)一個(gè)二元操作函數(shù)組合成一個(gè)單一的值。例如:valnumbers=List(1,2,3,4,5)valsum=numbers.reduce(_+_)//調(diào)用reduce函數(shù),得到15在這個(gè)例子中,_+_是一個(gè)匿名函數(shù),它接受兩個(gè)參數(shù)并將它相加。下劃線_在這里表示函數(shù)的參數(shù),而+是這兩個(gè)參數(shù)之間的操作。由于reduce函數(shù)期望一個(gè)二元函數(shù)作為參數(shù),這個(gè)匿名函數(shù)正好滿足要求。它告訴reduce函數(shù),應(yīng)該將集合中的元素兩兩相加,直到得到一個(gè)單一的值15。這里的reduce(_+_)相當(dāng)于reduce((x,y)=>x+y)。1.5Scala類與模式匹配作為一個(gè)運(yùn)行一個(gè)JVM上的語(yǔ)言,Scala毫無(wú)疑問(wèn)首先是面向?qū)ο蟮恼Z(yǔ)言。盡管在具體的數(shù)據(jù)處理部分,函數(shù)式編程在Scala中已成為首選方案,但在上層的架構(gòu)組織上,仍然需要采用面向?qū)ο蟮哪P停@對(duì)于大型的應(yīng)用程序尤其必不可少。類的定義在Scala中,定義一個(gè)類使用class關(guān)鍵字,后面跟著類名和類體。類體中包含了類的成員變量(字段)和方法。例如:classPerson(valname:String,valage:Int){defgreet():String={"Hello,mynameis"+name+"andIam"+age+"yearsold."}}在這個(gè)例子中,定義了一個(gè)Person類,它有兩個(gè)成員變量name和age(使用val關(guān)鍵字表示這些變量是不可變的),以及一個(gè)方法greet用于打印問(wèn)候語(yǔ)。1.5.1Scala類2.成員變量和方法成員變量是類的屬性,用于存儲(chǔ)對(duì)象的狀態(tài)。在Scala中,可以使用val或var關(guān)鍵字來(lái)定義成員變量。val關(guān)鍵字表示變量是不可變的,而var關(guān)鍵字表示變量是可變的。方法是類的行為,用于執(zhí)行特定的操作。在Scala中,方法定義使用def關(guān)鍵字,后面跟著方法名和參數(shù)列表(可選),以及方法體。3.構(gòu)造器Scala中的類有一個(gè)主構(gòu)造器,它是類定義的一部分,用于初始化對(duì)象的成員變量。在上面的Person類例子中,主構(gòu)造器接受兩個(gè)參數(shù)name和age,并將它賦值給類的成員變量。除了主構(gòu)造器外,Scala還允許定義輔助構(gòu)造器。輔助構(gòu)造器使用this關(guān)鍵字來(lái)調(diào)用主構(gòu)造器或其他輔助構(gòu)造器。以下示例展示了Scala中主構(gòu)造器和輔助構(gòu)造器的定義和使用方法,以及如何通過(guò)不同的構(gòu)造器來(lái)創(chuàng)建具有不同屬性的對(duì)象。1.5.1Scala類在這個(gè)例子中,定義了一個(gè)Rectangle類,它有一個(gè)主構(gòu)造器和兩個(gè)輔助構(gòu)造器。主構(gòu)造器接受兩個(gè)參數(shù)width和height,用于初始化矩形的寬度和高度。輔助構(gòu)造器1接受一個(gè)參數(shù)side,用于創(chuàng)建一個(gè)正方形(即寬度和高度相等的矩形)。輔助構(gòu)造器2接受兩個(gè)參數(shù)area和aspectRatio,用于根據(jù)給定的面積和寬高比創(chuàng)建一個(gè)矩形。在RectangleExample對(duì)象的main方法中,使用主構(gòu)造器和輔助構(gòu)造器來(lái)創(chuàng)建Rectangle對(duì)象,并打印它的信息和面積。4.繼承Scala支持類的繼承,允許一個(gè)類繼承另一個(gè)類的屬性和方法。使用extends關(guān)鍵字來(lái)實(shí)現(xiàn)繼承。例如:classEmployee(name:String,age:Int,valsalary:Double)extendsPerson(name,age){defwork():String={"Iamworkingasanemployee."}}在這個(gè)例子中,Employee類繼承自Person類,并添加了一個(gè)新的成員變量salary和一個(gè)新的方法work。1.5.1Scala類5.類的使用以下是一個(gè)使用Scala類、繼承、構(gòu)造器和方法的完整示例:classAnimal(valname:String){defspeak():String={"Somegenericanimalsound"}}
classDog(name:String,valbreed:String)extendsAnimal(name){overridedefspeak():String={"Woof!Woof!"}}
objectMain{defmain(args:Array[String]):Unit={valanimal=newAnimal("GenericAnimal")println()//輸出:GenericAnimalprintln(animal.speak())//輸出:Somegenericanimalsound
valdog=newDog("Buddy","GoldenRetriever")println()//輸出:Buddyprintln(dog.breed)//輸出:GoldenRetrieverprintln(dog.speak())//輸出:Woof!Woof!}}在這個(gè)例子中,定義了一個(gè)Animal類和一個(gè)Dog類,其中Dog類繼承自Animal類并重寫了speak方法。然后,在Main對(duì)象的main方法中創(chuàng)建了Animal和Dog對(duì)象,并調(diào)用它的方法。1.5.2單例類單例類是一種特殊的類,有且只有一個(gè)實(shí)例。和惰性變量一樣,單例類的對(duì)象是延遲創(chuàng)建的,當(dāng)它第一次被使用時(shí)創(chuàng)建。當(dāng)對(duì)象定義于頂層時(shí)(即沒(méi)有包含在其他類中),單例類的對(duì)象只有一個(gè)實(shí)例。當(dāng)對(duì)象定義在一個(gè)類或方法中時(shí),單例對(duì)象表現(xiàn)得和惰性變量一樣。單例類通過(guò)在類定義上使用object關(guān)鍵字來(lái)實(shí)現(xiàn),而不是class。單例類在Scala中非常有用,特別是當(dāng)需要一個(gè)全局可訪問(wèn)的點(diǎn)來(lái)存儲(chǔ)數(shù)據(jù)或行為時(shí)。
在這個(gè)例子中,定義了一個(gè)名為SingletonExample的單例類,它有一個(gè)私有成員變量count,用于存儲(chǔ)計(jì)數(shù)值。此外,還定義了兩個(gè)方法increment和getCount,分別用于增加計(jì)數(shù)并返回新的計(jì)數(shù)值,以及獲取當(dāng)前的計(jì)數(shù)值。在Main對(duì)象的main方法中,演示了如何訪問(wèn)單例類的成員和方法。由于SingletonExample是一個(gè)單例類,因此無(wú)論調(diào)用多少次increment方法,它都會(huì)操作同一個(gè)count變量,從而實(shí)現(xiàn)計(jì)數(shù)值的累積。這個(gè)示例展示了Scala中單例類的定義和使用方法,以及如何通過(guò)單例類的成員和方法來(lái)存儲(chǔ)和訪問(wèn)全局?jǐn)?shù)據(jù)。//定義一個(gè)單例類objectSingletonExample{//單例類的成員變量privatevarcount=0
//單例類的方法,用于增加計(jì)數(shù)并返回新的計(jì)數(shù)值defincrement():Int={count+=1count}s
//單例類的方法,用于獲取當(dāng)前的計(jì)數(shù)值defgetCount():Int={count}}
objectMain{defmain(args:Array[String]):Unit={//訪問(wèn)單例類的成員和方法println(SingletonExample.getCount())//輸出:0println(SingletonExample.increment())//輸出:1println(SingletonExample.increment())//輸出:2println(SingletonExample.getCount())//輸出:2}}1.5.2單例類1.5.3模式匹配Scala有一個(gè)十分強(qiáng)大的模式匹配機(jī)制,可以應(yīng)用到很多場(chǎng)合:如switch語(yǔ)句、類型檢查等。并且Scala還提供了樣例類,對(duì)模式匹配進(jìn)行了優(yōu)化,可以快速進(jìn)行匹配。一個(gè)模式匹配包含了一系列備選項(xiàng),每個(gè)都開(kāi)始于關(guān)鍵字case。
每個(gè)備選項(xiàng)都包含了一個(gè)模式及一到多個(gè)表達(dá)式。箭頭符號(hào)=>隔開(kāi)了模式和表達(dá)式。1.6Python匿名函數(shù)、閉包和裝飾器Python匿名函數(shù)、閉包和裝飾器是Python函數(shù)式編程較為有特點(diǎn)的語(yǔ)言現(xiàn)象。以下將對(duì)其展開(kāi)具體的介紹。1.6.1Python的匿名函數(shù)在Python中,匿名函數(shù)是通過(guò)lambda關(guān)鍵字來(lái)創(chuàng)建的。lambda函數(shù)是一種簡(jiǎn)短的、定義在行內(nèi)的函數(shù),它沒(méi)有具體的函數(shù)名,因此也稱為匿名函數(shù)。這種函數(shù)通常用于需要將函數(shù)作為參數(shù)傳遞,或者需要一個(gè)簡(jiǎn)單的函數(shù)而不想用標(biāo)準(zhǔn)的def語(yǔ)法來(lái)定義一個(gè)完整的函數(shù)的情況。lambda關(guān)鍵字的用法lambda函數(shù)的語(yǔ)法如下:lambda參數(shù)列表:表達(dá)式其中,參數(shù)列表可以包含多個(gè)參數(shù),用逗號(hào)分隔,而表達(dá)式則是一個(gè)計(jì)算并返回結(jié)果的表達(dá)式。lambda函數(shù)只能包含一個(gè)表達(dá)式,并且這個(gè)表達(dá)式的結(jié)果就是函數(shù)的返回值。1.6.1Python的匿名函數(shù)2.lambda函數(shù)的特點(diǎn)和限制(1)?簡(jiǎn)潔性?:lambda函數(shù)提供了一種快速定義簡(jiǎn)單函數(shù)的方法,使得代碼更加簡(jiǎn)潔。(2)?匿名性?:由于lambda函數(shù)沒(méi)有函數(shù)名,因此也稱為匿名函數(shù)。(3)?單一表達(dá)式?:lambda函數(shù)只能包含一個(gè)表達(dá)式,不能包含命令式語(yǔ)句(如循環(huán)、條件語(yǔ)句等)。(4)?有限用途?:lambda函數(shù)通常用于簡(jiǎn)單的函數(shù)定義,對(duì)于復(fù)雜的函數(shù)邏輯,還是建議使用標(biāo)準(zhǔn)的def語(yǔ)法。#定義一個(gè)lambda函數(shù),用于計(jì)算兩個(gè)數(shù)的和add=lambdax,y:x+y
#使用lambda函數(shù)result=add(5,3)print(result)#輸出:8在這個(gè)示例中,定義了一個(gè)名為add的lambda函數(shù)(雖然它沒(méi)有真正的名字,但這里為了說(shuō)明方便,我們稱之為add),它接受兩個(gè)參數(shù)x和y,并返回它們的和。然后,我們使用這個(gè)lambda函數(shù)來(lái)計(jì)算5和3的和,并將結(jié)果打印出來(lái)。3.創(chuàng)建和使用lambda函數(shù)的示例下面是一個(gè)創(chuàng)建和使用lambda函數(shù)的簡(jiǎn)單示例:1.6.1Python的匿名函數(shù)4.lambda函數(shù)應(yīng)用場(chǎng)景l(fā)ambda函數(shù)通常應(yīng)用在需要使用函數(shù)對(duì)象的地方,但函數(shù)本身又很簡(jiǎn)單,不值得用一個(gè)標(biāo)準(zhǔn)的def語(yǔ)句來(lái)定義。以下是Python匿名函數(shù)的主要應(yīng)用場(chǎng)景及示例:(1)排序操作在排序操作中,可以使用lambda函數(shù)來(lái)指定排序的鍵(key)。例如,如果有一個(gè)包含元組的列表,并且想要根據(jù)元組的第二個(gè)元素進(jìn)行排序,可以這樣做:#定義一個(gè)包含元組的列表tuples=[(1,'one'),(2,'two'),(3,'three'),(4,'four')]
#使用lambda函數(shù)作為排序的鍵sorted_tuples=sorted(tuples,key=lambdax:x[1])
print(sorted_tuples)#輸出:[(4,'four'),(1,'one'),(3,'three'),(2,'two')]在這個(gè)例子中,lambdax:x[1]是一個(gè)匿名函數(shù),它接受一個(gè)參數(shù)x(這里是一個(gè)元組),并返回x的第二個(gè)元素(即字符串)。sorted函數(shù)使用這個(gè)匿名
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026年遼寧廣告職業(yè)學(xué)院?jiǎn)握芯C合素質(zhì)筆試模擬試題含詳細(xì)答案解析
- 2026年黑龍江三江美術(shù)職業(yè)學(xué)院?jiǎn)握芯C合素質(zhì)筆試模擬試題含詳細(xì)答案解析
- 智能時(shí)代的人工智能生存法則
- 2026秋招:新鳳鳴集團(tuán)試題及答案
- 2026秋招:沃得機(jī)電集團(tuán)面試題及答案
- 成人瑜伽私教協(xié)議(一對(duì)一)2025年場(chǎng)地使用規(guī)定
- 倉(cāng)庫(kù)收貨培訓(xùn)流程
- 保密協(xié)議(2026年客戶資料保密協(xié)議)
- 2026年春季學(xué)期XX市第四中學(xué)“跨學(xué)科融合”教學(xué)案例集(初一年級(jí):語(yǔ)文+科學(xué))
- 2025-2026學(xué)年秋季學(xué)期初三年級(jí)(21)班班主任班級(jí)管理工作計(jì)劃(下學(xué)期)
- DL-T 5861-2023 電化學(xué)儲(chǔ)能電站初步設(shè)計(jì)內(nèi)容深度規(guī)定
- 高中體育教師期末教學(xué)工作匯報(bào)
- 別克英朗說(shuō)明書
- 地下管線測(cè)繪課件
- 珍稀植物移栽方案
- 新人教版數(shù)學(xué)三年級(jí)下冊(cè)預(yù)習(xí)學(xué)案(全冊(cè))
- JJG 810-1993波長(zhǎng)色散X射線熒光光譜儀
- GB/T 34336-2017納米孔氣凝膠復(fù)合絕熱制品
- GB/T 20077-2006一次性托盤
- GB/T 1335.3-2009服裝號(hào)型兒童
- GB/T 10046-2008銀釬料
評(píng)論
0/150
提交評(píng)論