基礎(chǔ)06-組織、注釋引用代碼_第1頁(yè)
基礎(chǔ)06-組織、注釋引用代碼_第2頁(yè)
基礎(chǔ)06-組織、注釋引用代碼_第3頁(yè)
基礎(chǔ)06-組織、注釋引用代碼_第4頁(yè)
基礎(chǔ)06-組織、注釋引用代碼_第5頁(yè)
已閱讀5頁(yè),還剩17頁(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)介

第六章組織、注釋、代編程語(yǔ)言的一個(gè)很重要部分就是按照邏輯單元組織代碼的能力。為此,F(xiàn)#(namespaces,“命名空間和模塊”中討論。為了更好地理解F#的模塊系統(tǒng),除了在知道模塊是如何為了使模塊有效果,很重要地使模塊部分私有,從而不能從外部看到。為此,F(xiàn)#種途徑,在“函數(shù)類型表示文件“私有和內(nèi)部的let綁定和成員”兩節(jié)來(lái)討論。O’Caml交叉編譯而設(shè)計(jì)的;而其他更普通的在譯成數(shù)據(jù)結(jié)構(gòu)的技術(shù)叫(quoting,將在本章的結(jié)尾“代碼”一節(jié)討論。模塊塊(看這一章后面的“命名空間和模塊”一節(jié)。個(gè)模塊沒(méi)有顯式命名,那么源文件的名字,第一個(gè)字母大寫(xiě)就是它的名字(F#module。關(guān)鍵字有兩種操作模式:一種是整個(gè)源文件中modulebeginend。為了包裝模塊定義,可以嵌ThirdModule嵌套在SecondModule中://createatoplevelmodule//createafirstmodulemoduleFirstModule=letn=//createasecondmodulemoduleSecondModule=letn=//createathird//nestedinsidethesecondmoduleThirdModule=letn=在F#交互模式中,不能使用沒(méi)有等號(hào)的module關(guān)鍵字;當(dāng)使用沒(méi)有等號(hào)的module關(guān)F#F#module就會(huì)出錯(cuò);但是,仍可以在F#交互模式中使用有等號(hào)的module來(lái)創(chuàng)建子模塊。。識(shí)符之間不會(huì)面的例子中,三個(gè)模塊中都定義了標(biāo)識(shí)符n;下面的例子演示如何每個(gè)模塊中的標(biāo)識(shí)符n:。//unpackthevaluesdefinedineachmoduleletx=ModuleDemo.FirstModule.nlety=letz=這一段代碼會(huì)編譯成一個(gè).NET類,連同值一起,成為這個(gè)類中的方法和字段。在第十四章,會(huì)有有關(guān)F#的模塊與其他.NET編程語(yǔ)言相比較的細(xì)節(jié)。命名空間命名空間名是用點(diǎn)分隔的幾部分字符串組成。例如,F(xiàn)#提供一個(gè)模塊,名叫List,.NETBCL提供一個(gè)類,名字也叫List;但是,這并沒(méi)有命名,因?yàn)?,F(xiàn)#模塊在命名空間.FSharp下,而B(niǎo)CL類在命名空間System.Collections.Generic下。命名空間使編譯的代碼保持獨(dú)立,因此,不允許在F#交互中使用,因?yàn)?,這毫無(wú)意義。同。也可以顯式地為模塊定義命名空間,用namespace指令。例如,下面的定義:modulenamespaceStrangelights.BeginningmoduleModuleDemo因此,用namespace指令把子模塊放在命名空間中。例如://putthefileinanamespacenamespaceStrangelights.Beginning//createafirstmodulemoduleFirstModule=letn=//createasecondmodulemoduleSecondModule=letn=//createathird//nestedinsidethesecondmoduleThirdModule=letn=代碼編譯以后,從外部來(lái)看,n的第一個(gè)實(shí)例要用標(biāo)識(shí)符Strangelights.Foundation.FirstModule.n來(lái),而不能僅僅是FirstModule.n。把幾說(shuō),前面示例中的FirstModule和SecondModule也可以放在單獨(dú)名空間中;但是,不能單獨(dú)名空間中SecondModule和ThirdModule,因?yàn)?,ThirdModule是嵌套在SecondModule中的,不能為T(mén)hirdModule單獨(dú)名空間。不用module//anamespacedefinitionnamespaceStrangelights.Beginning//arecordtypeMyRecord={Field:string//anamespacedefinitionnamespaceStrangelights.Beginning//avaluedefintion,whichis//directlyinsideanamespaceletvalue="val"nameSystem.Console.Wriine("oopenSystemConsole.Wriine("oworld")Sysem.Collction然后,用Generic.List去創(chuàng)建泛型List類的實(shí)例。就像下面的代碼:open//createaninstanceofadictionaryletwordCountDict=newGeneric.Dictionary<string,使用部分限定名,比如Generic.Dictionary,可能會(huì)使程序難于。因此,應(yīng)該這樣使用,要么是名字加完整名空間,要么只有名字??梢訤#的模塊,但不能非F#庫(kù)函數(shù)中的類。如果模塊,就可以用簡(jiǎn)稱其中的值和類型。例如,下面的示例引用兩個(gè)模塊:.FSharp.Math.PhysicalConstants和.FSharp.Math.SI,這兩個(gè)都在FSharp.PowerPackc,光的速度,實(shí)現(xiàn)的著名等式e=mc2:openopen//letm=//lete=m*(c*有些認(rèn)為,應(yīng)該謹(jǐn)慎使用直接模塊,因?yàn)檫@樣會(huì)很難找到標(biāo)識(shí)符的。注意,F(xiàn)#庫(kù)函數(shù)的許多模塊不能直接事實(shí)上模塊通常可以分為兩類一部分是使用全稱的,另一部分是直接的;大多數(shù)模塊是使用全稱的,很少直接的。通常的原因是,直接模塊,會(huì)使你直接使用其中的運(yùn)算符。下面的例子自定義了一個(gè)模塊,包含了三個(gè)等號(hào)的運(yùn)算符,然后,這個(gè)模塊,使用這個(gè)運(yùn)算符://moduleofoperatorsmoduleMyOps=//checkequalityviahashcodelet(===)xy=x.GetHashCode()=//opentheMyOpsmoduleopenMyOps//usethetripleequaloperatorletequal=1===1letnEqual=1===同名模塊或類中的值,只要值的名字不同就行。在圖6-1中,可以看到了命名空間BCLArrayF#Array6-1VisualStudio方法。對(duì)于在F#中創(chuàng)建的模塊,只需要給這個(gè)模塊一個(gè)別名。模塊別名的語(yǔ)法,關(guān)鍵字module,加標(biāo)識(shí)符,加等號(hào),加想要應(yīng)用別名名空間或模塊的名字。下面的例子為命名空間.FSharp.Collections.Array3定義了別名//giveanaliastotheArray3moduleArrayThreeD=//createanmatrixusingthemodulealiasletmatrix=ArrayThreeD.create333函數(shù)類型表示文件(SignatureFiles)SignatureFiles,](private-i任何出現(xiàn)在函類型表示件中的定都公開(kāi)(puic)的,使用塊的任何都能;沒(méi)有出現(xiàn)函數(shù)類表示文中的定都私有的能在模塊建函數(shù)型表示.fsimli;還必須為VisualStudio中,函數(shù)類型表示文件必須放在解決方案資源管理器(SolutionExplorer)中的源Lib.fs//defineafunctiontobeexposedletfunkyFunctionx=x+":keepit//defineafunctionthatwillbehiddenletnotSoFunkyFunctionx=x+1現(xiàn)在,假設(shè)想創(chuàng)建的庫(kù)只想funkyFunction,而不想notSoFunkyFunction,應(yīng)該//exposeavalfunkyFunction:string->fsc-aLib.fsi結(jié)果,程序集名為L(zhǎng)ib.dll,類名為L(zhǎng)ib,公開(kāi)函數(shù)名為funkyFunction,私有函數(shù)名為私有和內(nèi)部(PrivateandInternal)letF#還有另法控制值或類型的可見(jiàn)性,即,把關(guān)鍵字private或internal直接放在let綁定的后面,使綁定成為私有或內(nèi)部。比如:letprivateaPrivateBinding="Keepthisprivate"letinternalaInternalBinding="Keepthisinternal"private使值或類型只在當(dāng)前模塊中可見(jiàn),關(guān)鍵字internal程序集中可見(jiàn)。關(guān)鍵字private和internal的意思大體上與C#中的相同。關(guān)鍵字internal專門(mén)對(duì)F#是不可見(jiàn)的。下面的示例使用關(guān)鍵字internal隱藏聯(lián)合類型://ThistypewillnotvisibleoutsidethecurrentassemblytypeinternalMyUnion=|Stringof|TwoStringsofstring*privateinternal隱藏對(duì)象的成員,只需要簡(jiǎn)單地把關(guān)鍵字private和internal直接放在關(guān)鍵字member的后面就行了。比如:namespaceStrangelight.BeginningtypeThing()=memberprivatex.PrivateThing()=memberx.ExternalThing()=[]privateinternal(interfacefiles,也提供了相似的功能,必須在兩個(gè)地方更新定義。對(duì)于兩次更新的問(wèn)題,我通常寧可使用關(guān)鍵字private和塊之前,通過(guò)例子可能更容易理解。假設(shè)有一個(gè)源文件ModuleOne.fs,代碼如下:module//sometexttobeusedbyanothermodulelettext="sometext"module//printoutthetextdefinedinModuleOneprintfn"ModuleOne.text:%s"ModuleOne.text這兩個(gè)模塊用下面令可以編譯成功fscModuleOne.fsModuleTwo.fs-o但是,用下面令編譯,就會(huì)出錯(cuò)fscModuleTwo.fsModuleOne.fs-oModuleTwo.fs(3,17):error:FS0039:Thenamespaceormodule'ModuleOne'isnot之所以出錯(cuò),是因?yàn)樵贛oduleTwo的定義中用到了ModuleOne,因此,在命令行中,ModuleOne必須出現(xiàn)在ModuleTwo的前面,否則,ModuleOne就不會(huì)在ModuleTwo的作VisualStudio(SolutionExplorer)中文件出現(xiàn)VisualStudio菜單改變文件的順序(如圖6-2。6-2VisualStudio大體來(lái)說(shuō),F(xiàn)計(jì)算,在頂層的所有語(yǔ)句或所有頂層的do語(yǔ)句都會(huì)執(zhí)行??聪旅娴拇a:module//statementsatthetop-levelprintfn"Thisisthefirstline"printfn"Thisisthesecond"http://avaluedefinedatthetop-levelletfile=lettemp=newSystem.IO.FileInfo("test.txt")inprintfn"Fileexists:%b"temp.ExistsThisisthefirstlineThisisthesecondFileexists:falseletModuleOne.fsmodule//thenthisoneshouldbeprintedprintfn"Thisisthethirdandfinal"ModuleTwo.fsmodule//thesetwolinesshouldbeprintedfirstprintfn"Thisisthefirstline"printfn"Thisisthe假設(shè)用下 fscModuleOne.fsModuleTwo.fs-oThisisthefirstlineThisisthesecond這可能出乎你的想像,但是,記住,這很重要,因?yàn)镸oduleOne不是最后傳遞給編譯器的里,ModuleOnemodule//thiswillbeprintedwhenthe//membernisfirstaccessedprintfn"Thisisthethirdandfinal"letn=ModuleTwo.fs:moduleModuleTwo//thesetwolinesshouldbeprintedprintfn"Thisisthefirstline"printfn"Thisisthesecond"http://functiontoaccessModuleOneletfunct()=printfn"%i"ModuleOne.nfscModuleOne.fsModuleTwo.fs-oThisisthefirstlineThisisthesecondThisisthethirdandfinal中的最后,要有一條頂層語(yǔ)句[不知道對(duì)不對(duì)?]。條件編譯(OptionalCompilation)]它可能很方便,例如,如果你想讓生成(build)的庫(kù)函數(shù)支持.NET1.1和2.0,并且,想包括額外的值和類型,以利用2.0版中的新功能。然而,不應(yīng)該這一技術(shù),要很慎F#defineFLAG#ifFLAG也可以使用VisualStudio的生成配置菜單(參見(jiàn)圖6-3。6-3VisualStudio注意,使用VisualStudio,可以添加兩個(gè)預(yù)定義的開(kāi)關(guān)[不是編譯符號(hào)]:DEBUG和TRACE。這是兩個(gè)專門(mén)的開(kāi)關(guān),因?yàn)樗鼈儠?huì)影響某些框架的方法。比如:通過(guò)調(diào)用Assert.Debug的斷言,只在定義了DEBUG符號(hào)時(shí)才觸發(fā)。是作為F#交互的代碼(如果你打算編譯這段代碼,需要引用System.Winows.Fors.dll:open//definealetform=new//dosomethingdifferentdependingifwe're//asacompiledprogramofasascript#ifCOMPILEDApplication.Runform類似的,F(xiàn)#交互定義了符號(hào)INCTIVE,因此,可以用來(lái)測(cè)試是否在交互模式。F#(//)開(kāi)始,直到這一行的結(jié)束。如下面的示//thisisasingle-line在F#中,單選注釋通常是首選,因?yàn)檫@個(gè)字符的輸入更快、更容易。(*thisisacomment(*thisisa通常,多行注釋只用于臨時(shí)注釋掉大段代碼。與其他大多數(shù)語(yǔ)言不同,F(xiàn)#釋,與O'Caml的注釋相同。如果多行注釋不封閉,會(huì)編譯出錯(cuò)。文檔注釋(Doc文檔注釋,可以從源文件中提取注釋,以XML或HTML的格式。這是非常有用的,因?yàn)?,這樣程序員就可以瀏覽代碼的注釋而不看源代碼。對(duì)于API的提供者尤其方便,因?yàn)榭梢灾缓途o隨其后的值、類型相關(guān)聯(lián)。下面的代碼使注釋thisisanexnation和值myString相關(guān)聯(lián):///thisisanexletmyString="thisisaXMLdocprog.fs,提取文檔注釋令如下:fsc-docdoc.xml產(chǎn)生的XML<?xmlversion="1.0"encoding="utf-<memberthisisanex<member然后,就可以用各種工具來(lái)處理這個(gè)XML文件,比如,Sandcastle /Sandcastle),它可以把XML文件轉(zhuǎn)換成更可讀的格式。我發(fā)現(xiàn),把Sandcastle和Sandcastle幫助文件(http: 成工具對(duì)有些記號(hào)的支持不好比如泛型和聯(lián)合類型等在第十二章將學(xué)習(xí)有關(guān)生成HTMLF#XMLsummary></summary>XML//////dividesthegivenparameterby//////thethingtobedividedbyletdivTenx=x/<?xmlversion="1.0"encoding="utf-<membername="M:AnotherProg.divTendividesthegivenparameterbythethingtobedividedby<member的XML或HTML中。交叉編譯的注釋(CommentsforCross為了能夠更方便地在F#與O'Caml之間進(jìn)行交叉編譯,F(xiàn)#把某些注釋當(dāng)作條件編譯符號(hào)(optionalcompilationsflags)看待。放在注釋(*F#F#*)之間的所有代碼將常的注釋出現(xiàn),因此,將會(huì)被忽略。類似地,F(xiàn)#(*IF-OCAML*)(*ENDIF-OCAML*)O'CamlF#O'Caml.ml,而printfn"ThiswillbeprintedbyanF#program"(*IF-Format.printf"ThiswillbeprintedbyanO'Camlprogram"F#ThiswillbeprintedbyanF#自定義特征(CustomAttributes)propertyoftheattribute的成員,頂層的值和do語(yǔ)句的特征的,且是編譯時(shí)的特征。因此,譯成特征或特性。property是類的成員。](reflection,do([]按約定,特征名都以字符串Attribute結(jié)尾,因此,特征ObsoletefunctionOneopenSystemletfunctionOne()=Obsoleteopen[<Obsolete("itisapointlessfunctionanyway!")>]letfunctionTwo()=()PrintingPermissionUnrestrictedopenSystem.Drawing.PrintingopenSystem.Security.Permissions[<PrintingPermission(SecurityAction.Demand,Unrestricted=true)>]letfunctionThree()=()openopenSystem.Drawing.PrintingopenSystem.Security.Permissions[<Obsolete;PrintingPermission(SecurityAction.Demand)>]letfunctionFive()=()子標(biāo)記一個(gè)類型和它所有的成員都是obsolete。openSystemtypeOOThing=valstringThing:stringnew()={stringThing=""}memberx.GetTheString()=x.string_thing如果打算在自己的程序中使用WinForms或WindowsPresentationFoundation(WPF)apartmentSTAThreaddoopenopenSystem.Windows.Formsletform=newForm()doSystem.Reflection.MemberInfoIsDefinedGetCustomAttributes這些方法在大多數(shù)用于反映的對(duì)象上是可用的,包括System.Type有標(biāo)記有Obsolete特征的類型:open//createalistofallobsoletetypesletobsolete=|>|>List.map(funassm->|>|>|>List.filter(funm->m.IsDefined(typeof<ObsoleteAttribute>,true))//printthelistsprintfn"%A"obsolete[System.ContextMarshalException;System.Collections.IHashCodeProvider; 術(shù),去分析編譯的代碼,叫做(。代碼(Quoted(quotationtree要表達(dá)式,把它放在<@@>運(yùn)算符之間//quotetheintegeroneletquotedInt=<@1@>//printthequotedintegerprintfn"%A"quotedIntValue下面的代碼定義一個(gè)標(biāo)識(shí)符,并用于//defineanidentifiernletn=1//quotetheidentifierletquotedId=<@n@>//printthequotedidentifierprintfn"%A"quotedIdPropGet(None,Int32n,//defineafunctionletincx=x+1//quotethefunctionappliedtoavalueletquotedFun=<@inc1@>//printthequotationprintfn"%A"Call(None,Int32inc(Int32),[Valueopen//quoteanoperatorappliedtotwooperandsletquotedOp=<@1+1@>//printthequotationprintfn"%A"quotedOpCall(None,Int32op_Addition[Int32,Int32,Int32](Int32,Int32),[Value(1),Value(1)])下面的示例了一個(gè)函數(shù),需要注意的是,現(xiàn)在的結(jié)果是Lambda表達(dá)式open//quoteananonymousletquotedAnonFun=<@funx->x+1//printthequotationprintfn"%A"quotedAnonFunLambdaCall(None,Int32op_Addition[Int32,Int32,Int32](Int32,Int32),[x,Value(1)]))與.FSharp.Quotations.Expr的差別聯(lián)合(discriminatingunion)很相似處理也很簡(jiǎn)單就是對(duì)它進(jìn)行模式匹配下面的示例定義一個(gè)函數(shù)interpretInt,anint”:open//afunctiontointerpretverysimplequotationsletinterpretIntexp=matchexp|Value(x,typ)whentyp=typeof<int>->printfn"%d"(x:?>|_->printfn"notan//te

溫馨提示

  • 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)論