1.下載安裝scala
2.配置環(huán)境變量:
a右擊我的電腦统求,單擊“屬性”池磁,進入如圖所示頁面平窘。下面開始配置環(huán)境變量掉丽,右擊【我的電腦】---【屬性】-----【高級系統(tǒng)設(shè)置】---【環(huán)境變量】跌榔,
? ?b設(shè)置SCALA-HOME變量:如圖,單擊新建捶障,在變量名一欄輸入:?SCALA-HOME??? ? ?? 變 ? ??量值一欄輸入:??D:\ProgramFiles\scala??? ??也就是scala的安裝目錄僧须,根據(jù)個人情況有所不 ??同,
??c?設(shè)置path變量:找到系統(tǒng)變量下的“path”如圖项炼,單擊編輯担平。在“變量值”一欄的最前面添加? ? ?如下的 code:?%scala_Home%\bin;%scala_Home%\jre\bin;??? 注意:后面的分號 ?; ?? ??不要漏掉芥挣。
??d?設(shè)置classpath變量:找到找到系統(tǒng)變量下的“classpath”如圖驱闷,單擊編輯,如沒有空免,則單擊“新建”,
“變量名”:ClassPath
“變量值”:.;%scala_Home%\bin;%scala_Home%\lib\dt.jar;%scala_Home%\lib\tools.jar.;?注意:“變量值”最前面的?.; ?不要漏掉盆耽。最后單擊確定即可蹋砚。
最后保存進入cmd檢驗:
2.學(xué)習(xí)基本語法:
val,常量聲明
var摄杂,變量聲明
?類型省略(默認類型)
?聲明省略(連續(xù)聲明)
?def坝咐,函數(shù)聲明
?無參函數(shù)
?type,類型聲明
?class析恢,類聲明
?object墨坚,對象聲明
val x:T valx:T=e
var x:T varx:T=e
val x=e varx=e
val x1,x2,x3 等價于 val x1;valx2;val x3
var x1,x2,x3:T=e等價于varxn:T=e
defabc(xn:T):T*=e
def adder(m:Int,n:Int)=m+n
defadder()=e
轉(zhuǎn)義序列:
\b \u0008 退格
\t \u0090制表符
\n \u0004 換行
\f \u000c 換頁
\r \u000d 回車
\” \u0022雙引號
\’ \u0027單引號
\\ \u005c反斜杠
【重載 a<<b 為a*(b+1)】
【重載 a-=b 為a-b*2】
注釋 //
建立文本文件,把后綴名改為scala映挂,使用記事本編寫
使用Eclipse等進行scala腳本建立泽篮、編寫
編譯
絕大部分scala腳本在運行前需先進行編譯
cmd下利用scalac盗尸、fsc對scala腳本進行編譯
運行
只包含簡單的語句時無需編譯,能直接運行帽撑,否則需先進行編譯泼各,運行編譯后生成的scala文件
cmd下利用scala運行
判斷(if表達式)
循環(huán)(while/do語句)
枚舉(for表達式)
匹配(match表達式)
異常處理(throw/try)
輸出(print/println)
輸入(readLine)
枚舉(for表達式)
?For表達式能用任意條件進行各種形式枚舉,而在枚舉的過程中能實現(xiàn)絕大部分的循環(huán)功能且不必使用變量亏拉。
?for(i <- e) E(i)
?for表達式包括發(fā)生器(i <- e)同函數(shù)體E(i)扣蜻,
?發(fā)生器是遍歷e中的元素,每一次枚舉名為i的新的val就被初始化
?對于每一次枚舉及塘,函數(shù)體E(i)都會執(zhí)行一次莽使,而其中的參數(shù)i由枚舉時進行賦值
?e可以是各種集合,包括數(shù)組笙僚、列芳肌、表達式等,或是有上下界的數(shù)值范圍:
?1 to 4 (1=
for語句除了對枚舉值進行操作并釋放該值外味咳,可以用以賦值庇勃,即把每一次枚舉的值記錄在集合中。
?for(i <- e) yield E(i)
?若E(i)由花括號括起槽驶,yield須在花括號外责嚷,即for(i <- e) yield {E(i)}
?val No=
for(i <- 1 to 4)
yield i
匹配(match表達式)
?match表達式類似于其他語言的switch語句,提供多個備選項中進行選擇
?a match{
?case ??1 => ??1
?case ??2 => ??2
?… …
?}
?若a匹配??1則執(zhí)行??1掂铐,若a匹配??2則執(zhí)行??2罕拂,如此類推
?a可以是數(shù)組、任意類型值等全陨, ????可以是對應(yīng)的值爆班、常量、變量辱姨、甚至是類型
?match表達式能用以直接賦值柿菩,如
val sign = a match{case ??1 => 123;case ??2 =>“123”}
?匹配是從上而下的
異常處理(throw/try)
Scala處理異常一般通過throw拋出一個異常并中止
要么捕獲并處理該異常雨涛,要么簡單中止之
異常拋出:throw newIllegalArgumentException
異常捕獲與處理:try{函數(shù)體}catch{case…枢舶;case…}
異常捕獲并中止:try{函數(shù)體}finally{A.close()}
try{函數(shù)體} catch{case…;case…}finally{A替久。close()}
throw凉泄、try-catch-finally表達式都能生成值
如:throw newIllegalArgumentException(“Error!”)
def f():Int=try{1}finally{2}
變長數(shù)組聲明與操作
importscala.collection.mutable.ArrayBuffer
val C= newArrayBuffer[T]()
聲明一個空的數(shù)組緩存,此時C是一個全為空的數(shù)組蚯根,數(shù)組元素為0
C += ??1 //C:ArrayBuffer(??1)
在數(shù)組尾部增加一個類型為T的元素??1
C +=(??2, ??3)//C:ArrayBuffer(??1 , ??2, ??3)
在數(shù)組尾部增加類型為T的元素??2,??3
C++=Array(??2, ??3)//C:ArrayBuffer(??1 , ??2, ??3, ??2, ??3)
在數(shù)組尾部增加數(shù)組Array(??2,??3)
C .trimEnd(1)//C:ArrayBuffer(??1 , ??2, ??3, ??2)
移除最后1個元素
C .insert(2, ??3)//C:ArrayBuffer(??1 , ??2, ??3后众,??3, ??2)
在第二個元素后插入??3
C .insert(2,??1 , ??2, ??3)//C:ArrayBuffer(??1,??2,??1,??2, ??3,??3,??3, ??2)
在第二個元素后插入??1 , ??2,??3
C.remove(3)//C:ArrayBuffer(??1,??2,??1,??3,??3,??3, ??2)
移除第三個元素后的一個元素
C.remove(3,2)//C:ArrayBuffer(??1,??2,??1,??3, ??2)
移除第三個元素后的兩個元素
D=C.toArray把變長數(shù)組C轉(zhuǎn)換為定長數(shù)組D
E=A.toBuffer把定長數(shù)組A轉(zhuǎn)換為變長數(shù)組E
zip方法能把幾個集合結(jié)合起來
valone=Array(‘a(chǎn)’,‘b’蒂誉,‘c’)
valtwo=Array(1教藻,2,3)
val three=one.zip(two)或 valthree=one zip?
內(nèi)層能調(diào)用外層聲明的量
{val a=b...{val b=0...}...}外層不能調(diào)用內(nèi)層聲明的量
內(nèi)層聲明與外層聲明相同時拗盒,內(nèi)層使用的是內(nèi)層的聲明怖竭,外層使用的是外層的聲明
類定義
class HELLOWORLD{
private val value1 = “HELLO”
var value2 = “WORLD“
def add() { println(value1+value2)}
def plus(m:Char)=value2+m
}
類成員主要包括字段(val跟var)、方法與函數(shù)(def)陡蝇,但Scala禁止使用同樣的名稱命名字段和方法痊臭,即既聲明一個value字段,又聲明一個value方法是不允許的
類成員可見性有兩種登夫,private(私有)跟public(公有)广匙,private需要聲明,public無需額外聲明
類聲明后利用new聲明對象
val one= newHELLOWORLD
getter恼策、setter
?Scala對每個類中的字段都提供getter和setter方法
?對于公有字段來說鸦致,其getter和setter方法同樣是共有的,對于私有字段來說涣楷,則是私有的
?var聲明的字段帶有g(shù)etter和setter方法(讀寫)
?val聲明的字段自帶有g(shù)etter方法(只讀)
?對于字段value1分唾,其getter形式為value1,并沒有setter方法
?對于字段value2狮斗,其getter和setter方法形式為value2和value2_=
?實際使用時绽乔,在類定義外,getter和setter方法使用是一致的碳褒,形如one.value2
?getter方法與setter方法的意義在于什么地方呢折砸?
getter方法與setter方法的意義在于控制類中私有對象的數(shù)據(jù)
?在類中可以通過重定義getter和setter方法獲取、有限制的修改私有字段
?class HELLOWORLD{
private var privatevalue1 = “HELLO”
var value2 = “WORLD“
def add() { println(value1+privatevalue2) }
def plus(m:Char)=value2+m
def value1 = privatevalue1
def value1_ = (newvalue1:String) {
if(newvalue1.length>privatevalue1.length)privatevalue1=newvalue1
} //若新的字段比原私有字段長沙峻,則更改睦授,否則保持私有字段不變
}
主構(gòu)造器
?每個類都有主構(gòu)造器,且與類定義交織在一起
?主構(gòu)造器的參數(shù)直接放置在類名之后
?class HELLOWORLD(val value1:String摔寨,varvalue2:String){...}
?主構(gòu)造器的參數(shù)被編譯成字段去枷,并在構(gòu)造對象時初始化傳入
?一個類若沒有顯式定義主構(gòu)造器自動擁有一個無參主構(gòu)造器
?若類中有直接執(zhí)行的語句(非定義的方法、函數(shù))是复,每次構(gòu)造對象時皆會執(zhí)行一次沉填,不論什么樣的構(gòu)造器類型
?如:class HELLOWORLD(val value1:String,varvalue2:String){
println(“HELLOWORLD IS CREATED”)
val value3=value1+value2
}
val two = new HELLOWORLD(“WELCOME”佑笋,“HOME”)
主構(gòu)造器的參數(shù)一般有四種:
?value:String
生成對象私有字段,對象中沒有方法使用value斑鼻,則沒有該字段
?private val/var value:String
私有字段蒋纬,私有的getter/setter方法
?val/var value:String
私有字段,公有的getter/setter方法
?@BeanProperty?val/var value:String
私有字段,共有的Scala和JavaBean的getter/setter方法
?class HELLOWORD private(主構(gòu)造器){ 類成員}
主構(gòu)造器私有蜀备,只能通過輔助構(gòu)造器構(gòu)造對象
輔助構(gòu)造器
?Scala類能有任意多的輔助構(gòu)造器
?輔助構(gòu)造器的名稱為this关摇,在類中定義
?輔助構(gòu)造器必須以一個主構(gòu)造器或其他已定義的輔助構(gòu)造器調(diào)用開始
?class HELLOWORLD{
private var value1=“”
private var value2=“”
def this(m:String){
this() //調(diào)用主構(gòu)造器
this.value1=m}
def this(m:String,n:String){
this(m) //調(diào)用已定義的輔助構(gòu)造器
this.value2=n}}
單例對象
?object語法定義了某個類的單個實例
?對象的構(gòu)造器在該對象第一次被使用時調(diào)用
?object語法結(jié)構(gòu)與class大致相同,除了object不能提供構(gòu)造器參數(shù)
?通常使用單例對象的環(huán)境:
?作為存放工具函數(shù)或常量的地方
?共享單個不可變實例
?利用單個實例協(xié)調(diào)某個服務(wù)
伴生對象
?當一個單例對象存在同名類的時候碾阁,稱為伴生對象
?class HELLOWORLD{...}
objectHELLOWORLD{...}
?類和其伴生對象可以互相訪問私有屬性输虱,但必須存在同一個源文件中
?類的伴生對象可以被訪問,但并不在作用域中脂凶,如;
class HELLOWORLD{...}
object HELLOWORLD{ def NOW{...} }
?HELLOWORLD類必須通過HELLOWORLD.NOW調(diào)用伴生對象中的NOW方法宪睹,而不能直接用NOW來調(diào)用
apply方法
?需要構(gòu)造有參數(shù)需求的伴生對象時,可定義并使用apply方法
?class HELLOWORLD(var m:String,n:Char){...}
object HELLOWORLD{
def apply(n:Char)=new HELLOWORLD(“”蚕钦,n)
}
?val hi=HELLOWORLD(‘j’)
重寫
?Scala中使用override保留字進行方法亭病、字段重寫
?class week extends month{
overridedef firstday = {...}
}
?override保留字實際使用類似與private,聲明這個保留字后的定義嘶居、聲明是對超類的重寫罪帖,因此,其也可以寫在類定義的參數(shù)中
?class week(overrideval lastday:String)extendsmonth{...}
?子類的重寫或修改Scala會檢查其超類邮屁,但是整袁,超類的修改并不會檢查其子類
?重寫包括字段和方法,但參數(shù)不同的方法可以不重寫
?class month{ def secondday(m:String)={...}}
?class week extends month{ def secondday ={...}}
規(guī)則:
?重寫def
?用val :利用val能重寫超類用沒有參數(shù)的方法(getter)
?用def:子類的方法與超類方法重名
?用var:同時重寫getter佑吝、setter方法坐昙,只重寫getter方法報錯
?重寫val
?用val:子類的一個私有字段與超類的字段重名,getter方法重寫超類的getter方法
?重寫var
?用var:且當超類的var是抽象的才能被重寫迹蛤,否則超類的var都會被繼承
class month{
val one = 25 //可在子類中用val重寫
var two = 15 //不可在子類中用var重寫民珍,因為不是抽象的
var three:Int
def firstday = //可在子類中用val重寫
def now = //可在子類中用var重寫
def now_ =
def lastday(m:Char)={} //可在子類中用def重寫
}
?子類中,def只能重寫超類的def盗飒,val能重寫超類的val或不帶參數(shù)的def嚷量,var只能重寫超類中抽象的var或者超類的getter/setter對
抽象
?不能被實例的類叫做抽象類
?抽象類的某個或某幾個成員沒有被完整定義,這些沒有被完整定義的成員稱為抽象方法或抽象字段
?用abstract保留字標記抽象類
?abstractyear{
val name:Array[String] //抽象的val逆趣,帶有一個抽象的getter方法
var num:Int //抽象的var蝶溶,帶有抽象的getter/setter方法
def sign//沒有方法體/函數(shù)體,是一個抽象方法
}
?只要類中有任意一個抽象成員宣渗,必須使用abstract標記
?重寫抽象方法抖所、抽象字段不需要使用override保留字
保護
?當一個類不希望被繼承、拓展時痕囱,可在類聲明前加上final保留字
?final class year{...}
?當一個類的某些成員不希望被重寫時田轧,可以在成員聲明前加上final保留字
?class year{ final def sign{...} }
?當超類中的某些成員需要被子類繼承,又不想對子類以外成員可見時鞍恢,在成員聲明前加上protected保留字
?protected[this]傻粘,將訪問權(quán)限定于當前對象每窖,類似于private[this]
?類中protected的成員對其子類可見,對其超類不可見
?class year{ protecteddef sign{...} }
多重繼承
?Scala不支持多重繼承弦悉,取而代之的是特質(zhì)
?一個子類只能擁有一個超類窒典,一個超類能擁有多個子類
?即:class week extends month,year是不合法的
?為什么稽莉?
?若一個子類繼承自不同的超類瀑志,不同的超類中同名成員子類不知如何處理
?多重繼承產(chǎn)生菱形繼承問題
?解決多重繼承可能導(dǎo)致的問題消耗的資源遠比多重繼承產(chǎn)生的價值高
?Scala使用特質(zhì)達到類似多重繼承的效果
?一個類可以擴展自一個或多個特質(zhì),一個特質(zhì)可以被多個類擴展
?特質(zhì)能限制被什么樣的類所擴展
使用
?特質(zhì)是Scala里代碼復(fù)用的基礎(chǔ)單元污秆,封裝了方法和字段的定義
?特質(zhì)的定義使用保留字trait劈猪,具體語法與類定義相似,除了不能擁有構(gòu)造參數(shù)
?traitreset{
def reset(m:Int,n:Int)=if(m>=n) 1 }
?一旦特質(zhì)被定義了混狠,就可以混入到類中
?class week extendsreset {...}
?當要混入多個特質(zhì)時岸霹,利用with保留字
?class week extendsreset withB withC {...}
?特質(zhì)中的成員能是抽象的嗎?
?備注:所有JAVA接口都能當做是特質(zhì)使用在Scala中
特質(zhì)的成員可以是抽象的将饺,而且贡避,不需要使用abstract聲明
?同樣的,重寫特質(zhì)的抽象方法無需給出override
?但是予弧,多個特質(zhì)重寫同一個特質(zhì)的抽象方法需給出override
?除了在類定義中混入特質(zhì)以外刮吧,還可以
?在特質(zhì)定義中混入特質(zhì):
?trait reseting extendsreset{...}
?在對象構(gòu)造時混入特質(zhì)
?val five = new month withreseting
構(gòu)造
?特質(zhì)的構(gòu)造是有順序的,從左到右被構(gòu)造
?構(gòu)造器按如下順序構(gòu)造:
?超類
?父特質(zhì)
?第一個特質(zhì)
?第二個特質(zhì)(父特質(zhì)不重復(fù)構(gòu)造)
? ?類
如果class A extends B1 with B2 with B3....
?那么掖蛤,串接B1杀捻、B2、B3...等特質(zhì)蚓庭,去掉重復(fù)項且右側(cè)勝出
應(yīng)用
?特質(zhì)的一個主要應(yīng)用方面在于接口致讥,根據(jù)類已有的方法自動為類添加方法
?利用特質(zhì)實現(xiàn)富接口:
?構(gòu)造一個具有少量抽象方法和大量基于抽象方法的具體方法的特質(zhì)
?那么,只要把特質(zhì)混入類中器赞,通過類重寫抽象方法后垢袱,類便自動獲得大量具體方法
?trait Logger{
def log(msg:String)
def warn(msg:String) { log(“server”+msg) }
def server(msg:String) { log(“server”+msg) }}
class week extends Logger{
def log(msg:String){println(msg)}
server(“HI”)}
特質(zhì)的另一個應(yīng)用方面在于:為類提供可堆疊的改變(super保留字)
?當為類添加多個互相調(diào)用的特質(zhì)時,從最后一個開始進行處理
?在類中super.foo()這樣的方法調(diào)用是靜態(tài)綁定的港柜,明確是調(diào)用它的父類的foo()方法
?在特質(zhì)中寫下了super.foo()時请契,它的調(diào)用是動態(tài)綁定的。調(diào)用的實現(xiàn)講在每一次特質(zhì)被混入到具體類的時候才被決定
?因此夏醉,特質(zhì)混入的次序的不同其執(zhí)行效果也就不同
Scala語言入門
?高階函數(shù)
?Scala作為一門“函數(shù)式編程語言”爽锥,函數(shù)是一個值,能被傳遞和操作
?模式匹配
?match表達式的高級應(yīng)用畔柔,樣例類
?類型參數(shù)
?通過類型參數(shù)構(gòu)建類和函數(shù)氯夷、方法,使之適應(yīng)不同類型的參數(shù)
高階函數(shù)
?頭等函數(shù)
?匿名函數(shù)
?柯里化
柯里化是指將接受兩個參數(shù)的函數(shù)變成新的接受一個參數(shù)的函數(shù)的過程
?控制抽象
模式匹配
?模式匹配
模式匹配是數(shù)據(jù)結(jié)構(gòu)上的概念
?val hi=Array("hi","hello","world")
?hi match{
?case Array(“hi”, _*) => println(“Ok”)
?case Array("hi","world",_) => println("Wrong")
?case _ => println(“None") }
?數(shù)據(jù)結(jié)構(gòu)包括各種集合靶擦,類肠槽,函數(shù)等
?通配符“_”表示任意擎淤,“_*”則表示任意長度,
?樣例類
?封閉類
?偏函數(shù)
類型參數(shù)
?泛型
?類型變量界限
?型變(協(xié)變與逆變)
泛型
?類秸仙、特質(zhì)、函數(shù)桩盲、方法可帶有類型參數(shù)
?def getType(a:Any)//a是Any類型
?def getType[T](a:T)//a是泛型寂纪,getType是泛型函數(shù)
?class Pair[T,S](val first:T,val second:S)//泛型類
?trait Pair[T] //泛型特質(zhì)
?當類型被指定的時候構(gòu)成具體的類、函數(shù)等
?val getInt = getType[Int] _
?支持類型推斷
?val p1=new Pair[25,25.0] //生成Pair[Int,Double]類
?val p2=new Pair[25.0,25]
類型參數(shù)界限
?對于泛型結(jié)構(gòu)赌结,類型參數(shù)界限能限制應(yīng)用在該泛型上的類型
?Ordered[T]:Scala標準庫中提供的一個特質(zhì)捞蛋,用以表示可比較的類型
?abstract class Stack[ T <: Ordered[T]]
?class EmptyStack[T <: Ordered[T]] extends Stack[T]
?class NonEmptyStack[ T <: Ordered[T]](elem:T,rest:Stack[T])extends Stack[T]
?可以通過自行構(gòu)建的類混入Ordered特質(zhì)使之符合參數(shù)界限(能比較)
?類型參數(shù)上界實則通過限制類型必須擁有某些特質(zhì)
?T <: Compatable[T]
?T <: Integral[T]
類型參數(shù)界限
?abstract class Stack[ T <: Ordered[T]]
?class EmptyStack[T <: Ordered[T]] extends Stack[T]
?class NonEmptyStack[ T <: Ordered[T]](elem:T,rest:Stack[T])extends Stack[T]
?val m=EmptyStack[Int]
?Int不是Ordered[Int]的子類,但RichInt是
?視界限定
?T
注解
注解的是在編譯和運行之外柬姚,對程序進行的操作
? 自動生成文檔
? 在生成文檔時自動排版
? 代碼的錯誤檢查與忽略
? 注解的實質(zhì)是一個標簽拟杉,插入到代碼中標志元編程工具對該段代碼使用
? Java的注解并不影響編譯器的運行,但Scala的注解會量承,如@BeanProperty
? 可以自行編寫新的元編程工具
注解語法
? Scala可以為任意的結(jié)構(gòu)代碼甚至是參數(shù)添加注解
??@deprecated?def Sum() = { ... } //為方法添加注解
??@deprecated?class IntStack { ... } //為類添加注解
? def check(@NotNull?password:String) //為參數(shù)添加注解
? Scala支持多注解搬设,且注解次序沒有影響
??@BeanProperty?@Id?var username = _
? 部分注解需要引入?yún)?shù),Scala支持任意類型作為注解參數(shù)
??@Test( timeout = 100 ) def testA() = { ... }
注解語法
? 給主構(gòu)造器添加注解時撕捍,需要將注解放置在構(gòu)造器之前拿穴,并加上一對圓括號
? class Credentials?@Inject() (var username: String, var password:String)
? 為表達式添加注解,在表達式后加上冒號忧风,然后是注解
? (myMap.get(key):?@unchecked) match { ... }
? 為類型參數(shù)添加注解
? class MyContainer[@specialized?T]
? 針對實際類型的注解應(yīng)放置在類型名稱之后
String?@cps[Unit]
注解舉例
? Scala擁有若干個標準注解
? 廢棄@deprecated
? 標示某段代碼(方法或類)不提倡使用默色,調(diào)用該段代碼將會收到廢棄警告
? 易變字段@volatile
? 標示相關(guān)變量將會被多個線程使用,使得多線程訪問具有預(yù)見性
? 自動的get/set方法對@scala.reflect.BeanProperty
? 添加該注解將會在編譯時自動產(chǎn)生對應(yīng)的get/set方法狮腿,注意不能在同一時間編譯的代
碼中調(diào)用注解字段的get/set方法
不檢查@unchecked
生成跳轉(zhuǎn)表@switch
? (m :?@switch) match {
? case 0 => ...
? case 1 => ...
? case 2 => ... }
? 基本類型特殊化@specialized
? def sum[@specialized(Int , Double) T] = { ... }
并發(fā)
? 什么是并發(fā)腿宰?
? 將一個計算任務(wù),分成幾個小的部份缘厢,讓它們同時被計算吃度,之后再匯整計算結(jié)果
? 常見的并發(fā)結(jié)構(gòu)
? 多線程,分布式計算昧绣,消息傳遞规肴,資源共享(內(nèi)存共享)
? 常用的并發(fā)模型
? 參與者模式
? Petri網(wǎng)
? 通信順序進程
Actor
? 參與者模式Actor model
? 當一個參與者接收到一則訊息,它可以做出一些決策夜畴、建立更多的參與者拖刃、傳送更多
的訊息、決定要如何回答接下來的訊息
? Scala使用Actor作為其并發(fā)編程模型
? 一種基于消息傳遞而非資源共享的并發(fā)模型贪绘,能盡可能避免死鎖和共享狀態(tài)
? actor可以理解為虛擬線程兑牡,能實現(xiàn)線程的復(fù)用,從而產(chǎn)生數(shù)百上千的actor并有效控制
系統(tǒng)開銷
? Scala在2.10.0版本之后在自帶Akka類庫作為其Actor推薦實現(xiàn)
? Akka是使用Scala編寫的實現(xiàn)Actor模型的一個類庫
? Akka包括了大量的工具去完善税灌、輔助并發(fā)開發(fā)
使用actor需要引入Scala的Actor類庫
? import scala.actors.Actor
? import akka.actor.Actor
? 繼承Actor以使用
? class HI extends Actor
? object HELLO extends Actor
? 利用actor方法聲明使用
? val hi = actor { receive { ... } }
? val hello = Array.fill()( actor { react { case _ => } } )
消息傳遞是Actor的核心
? 使用均函!向actor發(fā)送信息
? actor使用receive接收信息
? msg代表actor當前接收到的信息
? 對于信息亿虽,actor往往使用模式匹配來進行處理,而對于消息的發(fā)送者而言苞也,其并不關(guān)
心actor接收到信息后如何處理洛勉,更不期待actor對該信息有返回,當消息發(fā)送后如迟,發(fā)送
者便處理下一步
? receive方法的參數(shù)有各種case語句組成收毫,receive方法獲取到消息后依次傳遞給其參數(shù)
actor通過react實現(xiàn)線程的復(fù)用
? receive從線程池獲取一個線程并一直使用,react從線程池獲取一個線程殷勘,使用完釋放
? def act( ) { react { ... } }
? actor(Scala.Actor)的主體為act方法此再,act方法不能被外部顯式調(diào)用
? actor的act方法在start后啟動,act方法本身并不會自動獲取線程
? 在act方法里只能獲取一次線程
? 在以下情況下actor終止執(zhí)行act方法
? act方法返回
? act方法由于異常被禁止
? actor調(diào)用exit方法
Actor使用原則
? 避免共享
? 不調(diào)用方法
? 足夠簡單
? 異步調(diào)用
? 使用react
? 容錯
更深入學(xué)習(xí)Scala
? XML處理
? 與JAVA的互操作
? Scaladoc
? 并發(fā)模型
? 深入學(xué)習(xí)Akka類庫的特性
??學(xué)習(xí)閱讀Scala的外語參考書玲销,如
? 《Actors in Scala》
? 《Scala Cookbooks》