多數(shù)時(shí)候直接用mixin不做翻譯_第1頁(yè)
多數(shù)時(shí)候直接用mixin不做翻譯_第2頁(yè)
多數(shù)時(shí)候直接用mixin不做翻譯_第3頁(yè)
多數(shù)時(shí)候直接用mixin不做翻譯_第4頁(yè)
多數(shù)時(shí)候直接用mixin不做翻譯_第5頁(yè)
已閱讀5頁(yè),還剩63頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

mixin混入組語(yǔ)言構(gòu)字重定子first一high高first一 ,第一章到第八章,翻譯于2009年11 cala無(wú)縫集成了面向?qū)ο蠛秃瘮?shù)式兩種編程模式。Scala可以用簡(jiǎn)潔、優(yōu)雅的代碼表達(dá)常見(jiàn)的程序邏輯,并且是類(lèi)型安全(tye-sfe)的,除此之外,它還引入了不少創(chuàng)新的語(yǔ)言構(gòu)詞,例如: types)和混入組合(mixincomposition,類(lèi)似于多繼承)作用在類(lèi)體系上的模式匹配(Patternmatching)靈活的語(yǔ)法和類(lèi)別系統(tǒng),便于構(gòu)建高級(jí)類(lèi)庫(kù)和新的領(lǐng)域語(yǔ)言(specificScalasmoothlyintegratesobject-orientedandfunctionalprogramming.Itisdesignedtoexpresscommonprogrammingpatternsinaconsise,elegant,andtype-safeway.Scalaintroducesseveralinnovativelanguageconstructs.Forinstance: typesandmixincompositionunifyconceptsfromobjectandmodule Patternmatchingoverclasshierarchiesunifiesfunctionalandobject-orienteddataaccess.ItgreatlysimplifiestheprocessingofXMLtrees. Aflexiblesyntaxandtypesystemenablestheconstructionofadvancedlibrariesand specificlanguages.Scala與Java完全兼容,Java的類(lèi)庫(kù)和框架可以直接在Scala中使用而無(wú)須額外的改造或者。本文檔通過(guò)一系列的例子,以非正式(非規(guī)范,informal)的形式向大家介紹Scala語(yǔ)本文第23兩章,挑出caa語(yǔ)言中一些有特色的特性加以展示,后面的章節(jié),則更加詳盡的介紹Scala中的各種語(yǔ)言構(gòu)詞和特性。從簡(jiǎn)單的表達(dá)式、函數(shù),到對(duì)象、類(lèi)、列表(lsts)、(strems、狀態(tài)變數(shù)(mtalestte,可變狀態(tài)和模式匹配相關(guān)的用法,再到一些展示編程技巧的完整例子。本文檔中的某些敘述可能不太正式,若需要了解Scla語(yǔ)言細(xì)節(jié)的準(zhǔn)確描述,可以參考ScalanaeRfrence。:本文從“StructureandInterpretationofComputerPrograms”[ASS96]這本書(shū)中借鑒了大量的例子,所以要對(duì)該書(shū)的作者Abelson’s和Sussman’s表示非常的感謝。當(dāng)然,例子中使用的語(yǔ)言,已經(jīng)從Scheme換成了Scala,并且在適當(dāng)?shù)牡胤剑昧薙cala面向?qū)ο蟮奶谹tthesametime,ScalaiscompatiblewithJava.Javalibrariesandframeworkscanbeusedwithoutgluecodeoradditionaldeclarations. introducesScalainaninformalway,throughasequenceofChapters2and3highlightsomeofthefeaturesthatmakeScalainteresting.ThefollowingchaptersintroducethelanguageconstructsofScalainamorethoroughway,startingwithsimpleexpressionsandfunctions,andworkingupthroughobjectsandclasses,listsandstreams,mutablestate,patternmatchingtomorecompleteexamplesthatshowinterestingprogrammingtechniques.ThepresentinformalexpositionismeanttobecomplementedbytheScalaLanguageReferenceManualwhichspecifiesScalainamoredetailedandpreciseAcknowledgment.WeoweagreatdebttoAbelson’sandSussman’swonderful“StructureandInterpretationofComputerPrograms”[ASS96].Manyoftheirexamplesandexercisesarealsopresenthere.Ofcourse,theworkinglanguagehasineachcasebeenchangedfromSchemetoScala.Furthermore,theexamplesmakeuseofScala’sobject-orientedconstructswhereappropriate.Asafirstexample,hereisanimplementationofQuicksortindefsort(xs:Array[Int])defswap(i:Int,j:Int)valt=xs(i);xs(i)=xs(j);xs(j)=}defsort1(l:Int,r:Int){valpivot=xs((l+r)/2)vari=l;varj=rwhile(i<=j)while(xs(i)<pivot)i+=1while(xs(j)>pivot)j-=1if(i<=j){swap(i,j)i+=1j-=}}if(l<j)sort1(l,if(j<r)sort1(i,}sort1(0,xs.length-}這段程序看起來(lái)和Java或者C的風(fēng)格類(lèi)似,其中用到了相同的操作符和類(lèi)似的控制結(jié)構(gòu)。定義(definitions)都以保留字開(kāi)始。def后面是函數(shù)定義,var后面是變量定義,值(value,相當(dāng)于常量)定義則以val開(kāi)始。符號(hào)(Symbol)的類(lèi)別跟在符號(hào)后面,中間用冒號(hào)(colon)分割。不過(guò)Scala的編譯器能夠根據(jù)上下類(lèi)型推斷(infer),所以類(lèi)型往往可以省略。數(shù)組類(lèi)型記為Array[T]而不是T[],數(shù)組的語(yǔ)法記為a(i)而不是a[i]函數(shù)內(nèi)部可以嵌套函數(shù)。內(nèi)嵌的函數(shù)可以包含它的函數(shù)的參數(shù)和局部變量。例如,上例中,數(shù)組xs對(duì)函數(shù)swap和sort1是可見(jiàn)的,所以無(wú)須再當(dāng)作參數(shù)傳給他們。TheimplementationlooksquitesimilartowhatonewouldwriteinJavaorC.Weusethesameoperatorsandsimilarcontrolstructures.Therearealsosomeminorsyntacticaldifferences.Inparticular: Definitionsstartwitha word.Functiondefinitionsstartwithdef,variabledefinitionsstartwithvaranddefinitionsofvalues(i.e.readonlyvariables)startwithval. Thedeclaredtypeofasymbolisgivenafterthesymbolandacolon.Thedeclaredtypecanoftenbeomitted,becausethecompilercaninferitfromthecontext. ArraytypesarewrittenArray[T]ratherthanT[],andarrayselectionsarewrittenratherthan Functionscanbenestedinsideotherfunctions.Nestedfunctionscanaccessparametersandlocalvariablesofenclosingfunctions.Forinstance,thenameofthearrayxsisvisibleinfunctionsswapandsort1,andthereforeneednotbepassedasaparameterto到目前為止,caa看起來(lái)只是一個(gè)有些語(yǔ)法特色的傳統(tǒng)語(yǔ)言,實(shí)際上,的確能夠以傳統(tǒng)(mprtve或者面向?qū)ο箫L(fēng)格來(lái)寫(xiě)Scala代碼,而且這種能力,可以簡(jiǎn)化Scala組件和其它主流語(yǔ)言(如jva,#)組件之間的整合。不過(guò),用Scala也可以寫(xiě)出風(fēng)格完全不一樣的代碼,下面的代碼,還是快速排序,但使用了函Sofar,Scalalookslikeafairlyconventionallanguagewithsomesyntacticpeculiarities.Infactitispossibletowriteprogramsinaconventionalimperativeorobject-orientedstyle.ThisisimportantbecauseitisoneofthethingsthatmakesiteasytocombineScalacomponentswithcomponentswritteninmainstreamlanguagessuchasJava,C#orVisualBasic.However,itisalsopossibletowriteprogramsinastylewhichlookscompleydifferent.HereisQuicksortagain,thistimewritteninfunctionalstyle.defsort(xs:Array[Int]):Array[Int]=if(xs.length<=1)elsevalpivot=xs(xs.length/2)sort(xsfilter(pivot>)),xsfilter(pivot==),sort(xsfilter(pivot<)))}}把數(shù)組中小于基準(zhǔn)和大于基準(zhǔn)的元素分別放進(jìn)兩個(gè)數(shù)組,等于基準(zhǔn)的元素放入第三個(gè)數(shù)組遞歸調(diào)用sort方法,對(duì)前兩個(gè)數(shù)組進(jìn)行排序1Thefunctionalprogramcapturestheessenceofthequicksortalgorithminaconcise Ifthearrayisemptyorconsistsofasingleelement,itisalreadysorted,soreturnit Ifthearrayisnotempty,pickananelementinthemiddleofitasa Partitionthearrayintotwosub-arrayscontainingelementsthatarelessthan,respectivelygreaterthanthepivotelement,andathirdarraywhichcontainselementsequaltopivot. Sortthefirsttwosub-arraysbyarecursiveinvocationofthesort Theresultisobtainedbyappendingthethreesub-arrays命令式和函數(shù)式兩種實(shí)現(xiàn)具有相同的時(shí)間復(fù)雜度-平為O(Nog(N,為O(N)不過(guò),命令式例子是在原數(shù)組上直接操作來(lái)實(shí)現(xiàn)排序,而函數(shù)式例子則不改變?cè)瓟?shù)組,返回的已排序數(shù)組都是新創(chuàng)建的,所以,函數(shù)式編程實(shí)現(xiàn)的快速排序,需要的trsit(臨時(shí))內(nèi)存。1在命令式編程的例子中,等于和大于基準(zhǔn)的元素是分到一個(gè)數(shù)組的,這是兩種實(shí)現(xiàn)之間的一點(diǎn)小差Thisisnotquitewhattheimperativealgorithmdoes;thelatterpartitionsthearrayintotwosub-arrayscontainingelementslessthanorgreaterorequaltopivot.函數(shù)式編程模式的快速排序例子,會(huì)讓人覺(jué)得,caa專(zhuān)門(mén)提供了很多用于數(shù)組操作的函數(shù)。實(shí)Sclaseuence類(lèi)SeqT]的方法,而標(biāo)準(zhǔn)類(lèi)庫(kù)本身也是caa實(shí)現(xiàn)的。因?yàn)閞ry是Seq的實(shí)例,所以可以使用它的所有方法(Scalafr循環(huán)是語(yǔ)言的能力,支持取字符串長(zhǎng)度,就是類(lèi)庫(kù)的能力。)。特別值得一提的是filter方法,它的參數(shù)是一個(gè)predicate函數(shù)(斷言函數(shù)),該函數(shù)把數(shù)組元素映射為布爾filter方法的返回值是一個(gè)數(shù)組,由原數(shù)組中能讓predicate函數(shù)返回true的元素構(gòu)成。filter方法的簽名如下:deffilter(p:T=>Boolean):其中,T=>Boolean定義了這樣一類(lèi)函數(shù):以類(lèi)型t為參數(shù)并返回Boolean值。像filter這樣把另一個(gè)函數(shù)當(dāng)作參數(shù)或者返回值的函數(shù),被稱為高階函數(shù)(higher-orderfunctions)。Boththeimperativeandthefunctionalimplementationhavethesameasymptoticcomplexity–O(Nlog(N))intheaveragecaseandO(N2)intheworstcase.Butwheretheimperativeimplementationoperatesincebymodifyingtheargumentarray,thefunctionalimplementationreturnsanewsortedarrayandleavestheargumentarrayunchanged.Thefunctionalimplementationthusrequiresmoretransientmemorythantheimperativeone.ThefunctionalimplementationmakesitlooklikeScalaisalanguagethat’sspecializedforfunctionaloperationsonarrays.Infact,itisnot;alloftheoperationsusedintheexamplearesimplelibrarymethodsofasequenceclassSeq[T]whichispartofthestandardScalalibrary,andwhichitselfisimplementedinScala.BecausearraysareinstancesofSeqallsequencemethodsareavailableforthem.Inparticular,thereisthemethodfilterwhichtakesasargumentapredicatefunction.Thispredicatefunctionmustmaparrayelementstobooleanvalues.Theresultoffilterisanarrayconsistingofalltheelementsoftheoriginalarrayforwhichthegivenpredicatefunctionistrue.ThefiltermethodofanobjectoftypeArray[T]thushasthesignaturedeffilter(p:T=>Boolean):Here,T=>BooleanisthetypeoffunctionsthattakeanelementoftypetandreturnaBoolean.Functionslikefilterthattakeanotherfunctionasargumentorreturnoneasresultarecalledhigher-orderfunctions.Scaa并不區(qū)分標(biāo)識(shí)符(identfirs)和操作符(opertrnams)。標(biāo)識(shí)符可以是以字符開(kāi)頭的字符和數(shù)字序列,也可以是由特殊字符組成的序列,比如“+”,“*”,或者“:”。在Scala中,所有的標(biāo)識(shí)符都可以用作中綴操作符。在語(yǔ)法上,二元運(yùn)算Eop`等價(jià)于E.o(`)(譯注:編譯器就是這么解釋的),無(wú)論這個(gè)二元中綴操作符op是不是以字符開(kāi)頭,所以,表達(dá)式xsfilter(pivot>)等價(jià)于xs.filter(pivot>)。在快速排序程序中,調(diào)了三次iler方法,每次都使用函數(shù)作為參數(shù)。以第一次調(diào)用時(shí)的參數(shù)“pivot”為例,它代表這樣一個(gè)函數(shù):接受參數(shù)x并返回表達(dá)式“pivot>x”的值,它實(shí)際上是“x=>pvot>x”的簡(jiǎn)化版,而這種簡(jiǎn)化語(yǔ)法,通常被稱為偏應(yīng)用函數(shù)(rtydfuction)。函數(shù)是的,而且參數(shù)x的類(lèi)型也省略了,因?yàn)榫幾g器可以從上下文自動(dòng)推斷類(lèi)型??偠灾瑇s.filter(pivot>)返回由xs中所有小于pivot的元素組成的新列表。Scaladoesnotdistinguishbetweenidentifiersandoperatornames.Anidentifiercanbeeitherasequenceoflettersanddigitswhichbeginswithaletter,oritcanbeasequenceofspecialcharacters,suchas“+”,“*”,or“:”.AnyidentifiercanbeusedasaninfixoperatorinScala.ThebinaryoperationEopE`isalwaysinterpretedasthemethodcallE.op(E`).Thisholdsalsoforbinaryinfixoperatorswhichstartwithaletter.Hence,theexpressionxsfilter(pivot>)isequivalenttothemethodcallxs.filter(pivot>).Inthequicksortprogram,filterisappliedthreetimestoananonymousfunctionargument.Thefirstargument,pivot>,representsafunctionthattakesanargumentxandreturnsthevaluepivot>x.Thisisanexampleofapartiallyappliedfunction.Another,equivalentwaytowritethisfunctionwhichmakesthemissingargumentexplicitisx=>pivot>x.Thefunctionisanonymous,i.e.itisnotdefinedwithaname.ThetypeofthexparameterisomittedbecauseaScalacompilercaninferitautomaticallyfromthecontextwherethefunctionisused.Tosummarize,xs.filter(pivot>)returnsalistconsistingofallelementsofthelistxsthataresmallerthanpivot.回過(guò)頭再來(lái)仔細(xì)研究快速排序的第一種實(shí)現(xiàn)(命令式),我們發(fā)現(xiàn),在第二種實(shí)現(xiàn)(函數(shù)式)中用到的一些語(yǔ)言構(gòu)詞,在第一種實(shí)現(xiàn)中也出現(xiàn)了,只不過(guò)形式更加隱蔽(disused,原意是)。例如,“標(biāo)準(zhǔn)”二元操作符+、-、或者<等,在程序中以很自然的形式出現(xiàn),不需要特殊處理(譯注:也就是說(shuō),可以直接寫(xiě)x+y,而無(wú)須寫(xiě)x.+(y)),就像append一樣(譯注:個(gè)人認(rèn)為應(yīng)該是前面提到多次的filter方法),它們都是左操作數(shù)上的方法。因此,表達(dá)式i+1可以認(rèn)為是調(diào)用整數(shù)x(譯注:應(yīng)該是i)上的+方法,也就是i.+(1)。當(dāng)然,編譯器可以自行決定是否識(shí)別“在整數(shù)上調(diào)用+方法”這樣的特殊模式,并為其生成高效率的內(nèi)聯(lián)代碼(inlinecode)。考慮到效率和更好的錯(cuò)誤診斷能力,while循環(huán)被設(shè)計(jì)成Scala的一個(gè)原子構(gòu)詞(primitivedefWhile(p:=>Boolean)(s:=>Unit)if(p){s;While(p)(s)}Lookingagainindetailatthefirst,imperativeimplementationofQuicksort,wefindthatmanyofthelanguageconstructsusedinthesecondsolutionarealsopresent,albeitinadisguisedForinstance,“standard”binaryoperatorssuchas+,-,or<arenottreatedinanyspecialway.Likeappend,theyaremethodsoftheirleftoperand.Consequently,theexpressioni+1isregardedastheinvocationi.+(1)ofthe+methodoftheintegervaluex.Ofcourse,acompileris(ifitismoderaysmart,evenexpected)torecognizethespecialcaseofcallingthe+methodoverintegerargumentsandtogenerateefficientinlinecodeforit.ForefficiencyandbettererrordiagnosticsthewhileloopisaprimitiveconstructinScala.Butinprinciple,itcouldhavejustaswellbeenapredefinedfunction.Hereisapossibleimplementationofit:defWhile(p:=>Boolean)(s:=>{if(p){s;While(p)(s)}While函數(shù)的第一個(gè)參數(shù)是條件檢查函數(shù),無(wú)參,返回boolean值;第二個(gè)參數(shù)是動(dòng)作函數(shù),無(wú)參,返回Unit類(lèi)型的值。只要條件檢查函數(shù)返回true,While就會(huì)執(zhí)行動(dòng)作函數(shù)。Scala中的Unit類(lèi)型大致對(duì)應(yīng)java中的void,主要用來(lái)表示函數(shù)不需要有意義的返回值的情況。差異在與,java中的void表示該函數(shù)沒(méi)有返回值;而Scala是面向表達(dá)式的語(yǔ)言(exrssion-rieted),所以每個(gè)函數(shù)都要有返回值,當(dāng)沒(méi)有顯式指定時(shí),默認(rèn)為(,也就是“ut”nt的函數(shù)也被稱為過(guò)程(rcrs)。如果把第一種實(shí)現(xiàn)中的swap函數(shù),用更規(guī)范的“面向表達(dá)式”方式來(lái)重寫(xiě),就應(yīng)該把unt顯式寫(xiě)出來(lái),參照如下代碼:defswap(i:Int,j:Int)valt=xs(i);xs(i)=xs(j);xs(j)=t}TheWhilefunctiontakesasfirstparameteratestfunction,whichtakesnoparametersandyieldsabooleanvalue.AssecondparameterittakesacommandfunctionwhichalsotakesnoparametersandyieldsaresultoftypeUnit.Whileinvokesthecommandfunctionaslongasthetestfunctionyieldstrue.Scala’sUnittyperoughlycorrespondstovoidinJava;itisusedwheneverafunctiondoesnotreturnaninterestingresult.Infact,becauseScalaisanexpression-orientedlanguage,everyfunctionreturnssomeresult.Ifnoexplicitreturnexpressionisgiven,thevalue(),whichispronounced“unit”,isassumed.ThisvalueisoftypeUnit.Unit-returningfunctionsarealsocalledprocedures.Here’samore“expression-oriented”formulationoftheswapfunctioninthefirstimplementationofquicksort,whichmakesthisexplicit:defswap(i:Int,j:Int)valt=xs(i);xs(i)=xs(j);xs(j)=t}該函數(shù)的返回值就是最后一行表達(dá)式的值,return不是必須的。對(duì)于顯式定義了返回值的函數(shù),在函數(shù)體之前(類(lèi)型和函數(shù)體之間)必須要加上“”。Theresultvalueofthisfunctionissimplyitslastexpression–areturnkeywordisnotnecessary.Notethatfunctionsreturninganexplicitvaluealwaysneedan“=”beforetheirbodyordefiningexpression.Scaa特別適用于解決某些領(lǐng)域的問(wèn)題,接下來(lái)我們就要舉一個(gè)這樣的例子。假如我們要實(shí)現(xiàn)一個(gè)電子拍賣(mài)服務(wù),我們使用Erlag風(fēng)格的actr處理模型來(lái)實(shí)現(xiàn)拍賣(mài)的參與者。Actrs是一種我們可以向其發(fā)送消息的對(duì)象,每個(gè)Actr使用queue來(lái)發(fā)向它的消息,我們把這個(gè)quue稱為mailbox。Actr可以順序處理malbox中的消息,也可以從中檢索符合特定模式的消息。對(duì)于每一件拍品,有一個(gè)對(duì)應(yīng)拍賣(mài)師的ctr,拍賣(mài)師負(fù)責(zé)發(fā)布拍品的信息,接受客戶的出價(jià),聯(lián)系賣(mài)家和中標(biāo)者并在適當(dāng)?shù)臅r(shí)候關(guān)閉。接下來(lái)的例子將展現(xiàn)總體的實(shí)現(xiàn)思路。首先,我們要定義一次拍賣(mài)過(guò)程中會(huì)交換什么信息。有兩個(gè)抽象的消息基類(lèi):AuctionMessage表示從客戶到拍賣(mài)方的消息;AuctionReply表示從拍賣(mài)方到客戶的消息。每種基類(lèi)都存在一定數(shù)量的個(gè)例(cases,譯注:個(gè)例,案例,或者說(shuō)子類(lèi),正好對(duì)應(yīng)Scala的條件類(lèi)caseclass),Here’sanexamplethatshowsanapplicationareaforwhichScalaisparticularlywellsuited.Considerthetaskofimplementinganelectronicauctionservice.WeuseanErlang-styleactorprocessmodeltoimplementtheparticipantsoftheauction.Actorsareobjectstowhichmessagesaresent.Everyactorhasa“mailbox”ofits ingmessageswhichisrepresentedasaqueue.Itcanworksequentiallythroughthemessagesinitsmailbox,orsearchformessagesmatchingsomepattern.Foreverytradeditemthereisanauctioneeractorthatpublishesinformationaboutthetradeditem,thatacceptsoffersfromsandthatcommunicateswiththesellerandwinningbiddertoclosethetransaction.Wepresentanoverviewofasimpleimplementationhere.Asafirststep,wedefinethemessagesthatareexchangedduringanauction.TherearetwobaseclassesAuctionMessageformessagesfromstotheauctionservice,andAuctionReplyforrepliesfromtheservicetothes.Forbothbaseclassesthereexistsanumberofcases,whicharedefinedinFigure3.1.importimportclasscaseclassOffer(bid: :Actor)extendscaseclassInquire(:Actor)extendsclasscaseclassStatus(asked:Int,expire:Date)extendscaseobjectBestOfferextendscaseclassBeatenOffer(maxBid:Int)extendsAuctionReplycaseclassAuctionConcluded(seller:Actor,:Actor)extendsAuctionReplycaseobjectAuctionFailedextendscaseobjectAuctionOverextends3.1對(duì)于每種基類(lèi),可以通過(guò)條件類(lèi)(caseclasses)來(lái)定義特定消息的格式。消息可能最終需要轉(zhuǎn)換成小段的XML文檔,我們期望有自動(dòng)化的工具可以完成內(nèi)外格式之間的互轉(zhuǎn)。代碼列表3.2是Auction類(lèi)的Scala代碼,該類(lèi)代表拍賣(mài)師的角色,用于協(xié)調(diào)一項(xiàng)拍品上的競(jìng)價(jià)。創(chuàng)建該類(lèi)的實(shí)例需要提供如下信息:最低價(jià)Foreachbaseclass,thereareanumberofcaseclasseswhichdefinetheformatofparticularmessagesintheclass.ThesemessagesmightwellbeultimaymappedtosmallXMLs.WeexpectautomatictoolstoexistthatconvertbetweenXMLsandinternaldatastructuresliketheonesdefinedabove.Figure3.2presentsaScalaimplementationofaclassAuctionforauctionactorsthatcoordinatethebiddingononeitem.Objectsofthisclassarecreatedbyindicating aselleractorwhichneedstobenotifiedwhentheauctionis aminimal thedatewhentheauctionistobeclassAuction(seller:Actor,minBid:Int,closing:Date)extendsActorvaltimeToShutdown valbidIncrement=defact()varmaxBid=minBid-varmaxBidder:Actor=nullvarrunning=truewhile(running)receiveWithin((closing.getTime()-newDate().getTime()))case )if(bid>=maxBid+bidIncrement)if(maxBid>=minBid)maxBidder!BeatenOffer(bid)maxBid=bid;maxBidder= !BestOffer}else!}case )!Status(maxBid,closing)caseTIMEOUTif(maxBid>=minBid)valreply=AuctionConcluded(seller,maxBidder)maxBidder!reply;seller!reply}elseseller!}receiveWithin(timeToShutdown)caseOffer(_,)=>!caseTIMEOUT=>running=}}}}}3.2:拍賣(mài)服務(wù)的實(shí)Actor的行為由act方法來(lái)實(shí)現(xiàn),該方法循環(huán)往復(fù)的調(diào)用receiveWithin來(lái)選擇消息并對(duì)消息出響應(yīng),直到拍賣(mài)結(jié)束,也就是遇到TIMEOUT消息。在真正停止之前,拍賣(mài)還會(huì)保持激活一段時(shí)間(長(zhǎng)度由timeToShutdown常量決定),在這段時(shí)間里,系統(tǒng)還會(huì)對(duì)新的出價(jià)請(qǐng)求做出響應(yīng),但只限于們拍賣(mài)已經(jīng)結(jié)束了。Thebehavioroftheactorisdefinedbyitsactmethod.Thatmethodselects(usingreceiveWithin)amessageandreactstoit,untiltheauctionisclosed,whichissignaledbyaTIMEOUTmessage.Beforefinallystop,itstaysactiveforanotherperioddeterminedbythetimeToShutdownconstantandrepliestofurtheroffersthattheauctionisActor類(lèi)的receiveWithin方法需要兩個(gè)參數(shù),一個(gè)是用毫秒表示的時(shí)間段;另一個(gè)是處理mailbox中消息的函數(shù),消息處理函數(shù)由一系列的cases構(gòu)成,每個(gè)case確定一個(gè)模式以及在匹配的消息上執(zhí)行的動(dòng)作。receiveWithin方法從mailbox中選receiveWithin方法的最后一個(gè)caseTIMEOUT模式。如果在給定的時(shí)間內(nèi)沒(méi)有收到任何消息,將會(huì)收到TIMEOUT消息,這是一個(gè)特殊消息,由Actor自己實(shí)現(xiàn)并發(fā)送應(yīng)答消息的語(yǔ)法格式為:destination!SomeMessage。!在這里是二元操作符,在Scala中,該語(yǔ)法格式等價(jià)于destination.!(SomeMessage),也就是說(shuō),用消息作為參數(shù),調(diào)用目標(biāo)的!方法。Herearesomefurtherexnationsoftheconstructsusedinthis ThereceiveWithinmethodofclassActortakesasparametersatimespangiveninmillisecondsandafunctionthatprocessesmessagesinthemailbox.Thefunctionisgivenbyasequenceofcasesthateachspecifyapatternandanactiontoperformformessagesmatchingthepattern.ThereceiveWithinmethodselectsthefirstmessageinthemailboxwhichmatchesoneofthesepatternsandappliesthecorrespondingactiontoit. ThelastcaseofreceiveWithinisguardedbyaTIMEOUTpattern.Ifnoothermessagesarereceivedintheme,thispatternistriggeredafterthetimespanwhichispassedasargumenttotheenclosingreceiveWithinmethod.TIMEOUTisaspecialmessage,whichistriggeredbytheActorimplementationitself. Replymessagesaresentusingsyntaxoftheformdestination!SomeMessage.!isusedhereasabinaryoperatorwithanactorandamessageasarguments.ThisisequivalentinScalatothemethodcalldestination.!(SomeMessage),i.e.theinvocationofthe!methodofthedestinationactorwiththegivenmessageasparameter.前面的討論,讓我們對(duì)Scala的分布式編程有了一些感覺(jué)。乍一看,Scala似乎提供了豐富的語(yǔ)言構(gòu)詞來(lái)支持基于Actr的處理、消息發(fā)送和接收、超時(shí)管理等等。實(shí)際上,正好相反,前面討論過(guò)的所有構(gòu)詞,都是類(lèi)的Actor類(lèi)的方法,而這個(gè)類(lèi)本身也是用Scala實(shí)現(xiàn)的,底(例如Jva或者,。.1Ato基于類(lèi)庫(kù)來(lái)實(shí)現(xiàn)Actor的優(yōu)點(diǎn)是:簡(jiǎn)化語(yǔ)言內(nèi)核,為類(lèi)庫(kù)設(shè)計(jì)者提供足夠的靈活性。因?yàn)檎Z(yǔ)言內(nèi)核不需要關(guān)心的進(jìn)程間通信的細(xì)節(jié),所以能保證它的簡(jiǎn)潔性和通用性。因?yàn)閙ilbx中的消息模型來(lái)自于類(lèi)庫(kù),所以,如果需要為特定應(yīng)用變更模型,這種方式更自由(不需要改語(yǔ)言內(nèi)核)。但是,這種實(shí)現(xiàn)模式,對(duì)語(yǔ)言內(nèi)核的表達(dá)能力有很高的要求,足夠靈活的內(nèi)核才能提供便捷的語(yǔ)言抽象的能力(譯注:就是后面說(shuō)的基于擴(kuò)展DSL的能力)。caa以此作為重要的指導(dǎo)思想,cla的主要設(shè)計(jì)目標(biāo)之一就是足夠靈活,從而為擴(kuò)展SL(spcfclaguge,領(lǐng)域語(yǔ)言)類(lèi)庫(kù)提供便利的宿主語(yǔ)言環(huán)境。例如,前面展示的actr通信構(gòu)詞,就可以看成是擴(kuò)展自cla內(nèi)核的一種DL。TheprecedingdiscussiongaveaflavorofdistributedprogramminginScala.ItmightseemthatScalahasarichsetoflanguageconstructsthatsupportactorprocesses,messagesendingandreceiving,programmingwithtimeouts,etc.Infact,theoppositeistrue.AlltheconstructsdiscussedaboveareofferedasmethodsinthelibraryclassActor.ThatclassisitselfimplementedinScala,basedontheunderlyingthreadmodelofthehostlanguage(e.g.Java,or.NET).TheimplementationofallfeaturesofclassActorusedhereisgiveninSectionTheadvantagesofthelibrary-basedapproacharerelativesimplicityofthecorelanguageandflexibilityforlibrarydesigners.Becausethecorelanguageneednotspecifydetailsofhigh-levelprocesscommunication,itcanbekeptsimplerandmoregeneral.Becausetheparticularmodelofmessagesinamailboxisalibrarymodule,itcanbelymodifiedifadifferentmodelisneededinsomeapplications.Theapproachrequireshoweverthatthecorelanguageisexpressiveenoughtoprovidethenecessarylanguage ionsinaconvenientway.Scalahasbeendesignedwiththisinmind;oneofitsmajordesigngoalswasthatitshouldbeflexibleenoughtoactasaconvenienthostlanguageforspecificlanguagesimplementedbylibrarymodules.Forinstance,theactorcommunicationconstructspresentedabovecanberegardedasonesuch specificlanguage,whichconceptuallyextendstheScalacore.前面的例子讓我們對(duì)Scala可以做什么有了初步的印象,接下來(lái),要用更加系統(tǒng)化的方式,逐個(gè)介紹Scala的構(gòu)詞(constructs)。我們從最小粒度的表達(dá)式和函數(shù)開(kāi)始。ThepreviousexamplesgaveanimpressionofwhatcanbedonewithScala.Wenowintroduceitsconstructsonebyoneinamoresystematicfashion.Westartwiththesmallestlevel,expressionsandfunctions.表達(dá)式和簡(jiǎn)單函數(shù)caa返回表達(dá)式的值和類(lèi)型。例如:AScalasystemcomeswithaninterpreterwhichcanbeseenasafancycalculator.Auserinctswiththecalculatorbytyinexpressions.Thecalculatorreturnstheevaluationresultsandtheirtypes.Forexample:scala>87+145res0:Int=scala>5+2*3res1:Int=11scala> o"+res2:java.lang.String 在解釋器中可以給表達(dá)式命名,接下來(lái)就可以用名字來(lái)該表達(dá)式Itisalsopossibletonameasub-expressionandusethenameinsteadoftheexpressionscala>defscale=5scale:Intscala>7*scaleres5:Int=35scala>defpi=3.141592653589793pi:Doublescala>defradius=10radius:Intscala>2*pi*res6:Double=用關(guān)鍵字def來(lái)定義一個(gè)名字,該名字就代表等號(hào)后面的表達(dá)式。解釋器將回顯新定義的名字def只做定義,但并不求右邊表達(dá)式的值,比如:defx=e,其中e的值在定義的時(shí)候不計(jì)算,而是e被的時(shí)候才計(jì)算。不過(guò),Scala還提供了一種定義值的:valx=e,這種方式在定義的時(shí)候就求出e的值賦給x,接下來(lái)用到x的時(shí)候,就直接用預(yù)先計(jì)算好的值替換,而無(wú)需再對(duì)e求值。表達(dá)式是如何求值的?表達(dá)式是由操作符和操作數(shù)構(gòu)成的,通過(guò)重復(fù)應(yīng)用如下步驟即可求出其值:Definitionsstartwiththe worddef;theyintroduceanamewhichstandsfortheexpressionfollowingthe=sign.TheinterpreterwillanswerwiththeintroducednameanditsExecutingadefinitionsuchasdefx=ewillnotevaluatetheexpressione.Insteadeisevaluatedwheneverxisused.Alternatively,Scalaoffersavaluedefinitionvalx=e,whichdoesevaluatetheright-hand-sideeaspartoftheevaluationofthedefinition.Ifxisthenusedsubsequently,itisimmediayrecedbythe putedvalueofe,sothattheexpressionneednotbeevaluatedagain.Howareexpressionsevaluated?Anexpressionconsistingofoperatorsandoperandsisevaluatedbyrepeatedlyapplyingthefollowingsimplificationsteps. picktheleft-most evaluateits applytheoperatortotheoperand對(duì)使用def定義的名字求值,就是用定義時(shí)的表達(dá)式替換該名字。對(duì)使用val定義的名字求值,Anamedefinedbydefisevaluatedbyrecingthenamebythe(unevaluated)definition’srighthandside.Anamedefinedbyvalisevaluatedbyrecingthenamebythevalueofthedefinitions’sright-handside.Theevaluationprocessstopsoncewehavereachedavalue.Avalueissomedataitemsuchasastring,anumber,anarray,oralist.例4.1.1求算術(shù)表(2*pi)*-- (2*3.141592653589793)*-- 6.283185307179586*-- 6.283185307179586*-- Theprocessofstepwisesimplificationofexpressionstovaluesiscalled參Usingdef,onecanalsodefinefunctionswithparameters.Forscala>defsquare(x:Double)=x*xsquare:(Double)Doublescala>square(2)res7:Double=4.0scala>square(5+3)res8:Double=64.0scala>square(square(4))res9:Double=256.0scala>defsumOfSquares(x:Double,y:Double)=square(x)+square(y)sumOfSquares:(Double,Double)Doublescala>sumOfSquares(3,2+2)res11:Double=25.0函數(shù)的參數(shù)寫(xiě)在函數(shù)名后面的括號(hào)里,在參數(shù)名后面跟著參數(shù)的類(lèi)型,其間用冒號(hào)做分割。到scal.Duble。caa為部分標(biāo)準(zhǔn)類(lèi)型定義了別名(typeliases),比如,double是scala.Doble的別名,而int是scaa.nt的別名,這樣數(shù)字類(lèi)型名就能和Java里保持一致了。對(duì)帶參數(shù)的函數(shù)求值,可以比照表達(dá)式中操作數(shù)求值的過(guò)程。首先,對(duì)函數(shù)的實(shí)參求值(從左向右),然后,用函數(shù)定義的右部替換函數(shù)調(diào)用,同時(shí)用實(shí)參的值替換對(duì)應(yīng)的形參。Functionparametersfollowthefunctionnameandarealwaysenclosedinparentheses.Everyparametercomeswithatype,whichisindicatedfollowingtheparameternameandacolon.Atthepresenttime,weonlyneedbasicnumerictypessuchasthetypescala.Doubleofdoubleprecisionnumbers.Scaladefinestypealiasesforsomestandardtypes,sowecanwritenumerictypesasinJava.Forinstancedoubleisatypealiasofscala.Doubleandintisatypealiasforscala.Int.Functionswithparametersareevaluatedogouslytooperatorsinexpressions.First,theargumentsofthefunctionareevaluated(inleft-to-rightorder).Then,thefunctionapplicationisrecedbythefunction’srighthandside,andatthesametimeallformalparametersofthefunctionarerecedbytheircorrespondingactualarguments.sumOfSquares(3,-- sumOfSquares(3,-- square(3)+--33+--9--94*--9--上例表明,解釋器是先對(duì)函數(shù)的參數(shù)求值,然后再用函數(shù)體替換函數(shù)調(diào)用。這個(gè)過(guò)程也可以反過(guò)來(lái),也就是在對(duì)參數(shù)求值以前,先用函數(shù)體替換函數(shù)調(diào)用,過(guò)程如下所示:Theexampleshowsthattheinterpreterreducesfunctionargumentstovaluesbeforerewritingthefunctionapplication.Onecouldinsteadhavechosentoapplythefunctiontounreducedarguments.Thiswouldhaveyieldedthefollowingreductionsequence:sumOfSquares(3,--square(3)+--3*3+--9+--9+(2+2)*--9+4*--9+4*--9+--上面的第二種求值順序通常叫做傳名調(diào)用(call-by- ),而第式叫做傳值調(diào)Cal-by-value的優(yōu)點(diǎn)是:可以免去對(duì)實(shí)參重復(fù)求值;Cal-by-ame的優(yōu)點(diǎn)是:可以避免對(duì)函數(shù)中壓根沒(méi)有用到的實(shí)參求值。Call-y-value的效率通常優(yōu)于cal-y-name,但某些通過(guò)cl-by-nme能求出值的表達(dá)式,使用cal-y-vale方式會(huì)導(dǎo)致死循環(huán)。例如,對(duì)于如下函數(shù)定義:Thesecondevaluationorderisknownascall-by-name,whereasthefirstoneisknownascall-by-value.Forexpressionsthatuseonlypurefunctionsandthatthereforecanbereducedwiththesubstitutionmodel,bothschemesyieldthesamefinalvalues.Call-by-valuehastheadvantagethatitavoidsrepeatedevaluationofarguments.Call-by-namehastheadvantagethatitavoidsevaluationofargumentswhentheparameterisnotusedatallbythefunction.Call-by-valueisusuallymoreefficientthancall-by-name,butacall-by-valueevaluationmightloopwhereacall-by-nameevaluationwouldterminate.scala>defloop:Int=looploop:Intscala>deffirst(x:Int,y:Int)=xfirst:(Int,Int)Int使用call-by-name方式對(duì)first(1,loop)求值得1,而用call-by-value則推導(dǎo)出來(lái)的結(jié)果與Thenfirst(1,loop)reduceswithcall-by-nameto1,whereasthesametermreduceswithcall-by-valuerepeatedlytoitself,henceevaluationdoesnotterminate.first(1,-- first(1,-- first(1,-- Scala默認(rèn)使用call-by-value方式,但如果函數(shù)的參數(shù)類(lèi)型前有“=>”前綴,則自動(dòng)切call-by-name方式Scalausescall-by-valuebydefault,butitswitchestocall-by-nameevaluationiftheparametertypeisprecededby=>.scala>defconstOne(x:Int,y:=>Int)=1constOne:(Int,=>Int)Intscala>constOne(1,loop)res12:Int=1scala>constOne(loop, //這里產(chǎn)生死循環(huán)^C//用Ctrl-C終止運(yùn)行(譯注:實(shí)際上似乎不行,只有關(guān)了窗口重來(lái)Scala中的if-else和java中的if-else語(yǔ)法類(lèi)似,作用類(lèi)似。但Scala中的if-else除了能控制語(yǔ)句的執(zhí)行順序,還可以起到j(luò)ava中的...?操作符一樣的作用。這是因?yàn)?,Scala中的if-else不僅執(zhí)行某個(gè)分支上的語(yǔ)句,而且本身會(huì)代表所執(zhí)行語(yǔ)句的值Scala’sif-elseletsonechoosebetweentwoalternatives.ItssyntaxislikeJava’sif-else.ButwhereJava’sif-elsecanbeusedonlyasanalternativeofstatements,Scalaallowsthesamesyntaxtochoosebetweentwoexpressions.That’swhyScala’sif-elseservesalsoasasubstituteforJava’sconditionalexpression...?...:....scala>defabs(x:Double)=if(x>=0)xelse-xabs:(Double)DoubleScala的布爾表達(dá)式和Java類(lèi)似,由布爾常量true、false,比較運(yùn)算符、布爾運(yùn)算符&&||Scala’sbooleanexpressionsaresimilartoJava’s;theyareformedfromtheconstantsandfalse,comparisonoperators,booleannegation!andthebooleanoperators&&and例子:用法求平方Wenowillustratethelanguageelementsintroducedsofarintheconstructionofamoreinterestingprogram.Thetaskistowriteafunctiondefsqrt(x:Double):Double=whichcomputesthesquarerootof求平方根最常見(jiàn)的辦法是使用的逐步近法:首先,選擇一個(gè)初始值y(比如y=1);然后,通過(guò)反復(fù)的求y和x/y的平均值來(lái)優(yōu)化初始值。接下來(lái)我們按照該算法,推演2的平方根,下面的三列分別代表本輪的猜測(cè)值y,x/y的商和前兩者平均值(也就是進(jìn)一步近的值)AcommonwaytocomputesquarerootsisbyNewton’smethodofsuccessiveap-proximations.Onestartswithaninitialguessy(say:y=1).Onethenrepeatedlyimprovesthecurrentguessybytakingtheaverageofyandx/y.Asanexample,thenextthreecolumnsindicatetheguessy,thequotientx/y,andtheiraverageforthefirstapproximationsof12/12/1.5=2/1.4167=y(y+在Scala中,可以用一組函數(shù)來(lái)實(shí)現(xiàn)該算法,每個(gè)函數(shù)表示該算法中的一個(gè)要素。首先要定義的是主迭代函數(shù),也就是從初始值向最終結(jié)果逐步近的主控函數(shù)。OnecanimplementthisalgorithminScalabyasetofsmallfunctions,whicheachrepresentoneoftheelementsofthealgorithm.WefirstdefineafunctionforitingfromaguesstothedefsqrtIter(guess:Double,x:Double):Doubleif(isGoodEnough(guess,x))elsesqrtIter(improve(guess,x),sqrtIter函數(shù)遞歸調(diào)用自己。命令式編程中的循環(huán)邏輯,在函數(shù)式編程中都可以用遞歸來(lái)實(shí)現(xiàn)sqrtIter函數(shù)的定義中包含了對(duì)返回值類(lèi)型的。遞歸函數(shù)是必須定義返回值類(lèi)型的,而非遞歸函數(shù)的返回值類(lèi)型是可選的;如果參與遞歸的函數(shù)沒(méi)有定義返回值類(lèi)型,則Scala會(huì)根據(jù)函的部行斷然,便非歸數(shù)也議確其型增程的讀NotethatsqrtItercallsi

溫馨提示

  • 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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論