基礎(chǔ)06-組織、注釋引用代碼_第1頁
基礎(chǔ)06-組織、注釋引用代碼_第2頁
基礎(chǔ)06-組織、注釋引用代碼_第3頁
基礎(chǔ)06-組織、注釋引用代碼_第4頁
基礎(chǔ)06-組織、注釋引用代碼_第5頁
已閱讀5頁,還剩17頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

第六章組織、注釋、代編程語言的一個很重要部分就是按照邏輯單元組織代碼的能力。為此,F(xiàn)#(namespaces,“命名空間和模塊”中討論。為了更好地理解F#的模塊系統(tǒng),除了在知道模塊是如何為了使模塊有效果,很重要地使模塊部分私有,從而不能從外部看到。為此,F(xiàn)#種途徑,在“函數(shù)類型表示文件“私有和內(nèi)部的let綁定和成員”兩節(jié)來討論。O’Caml交叉編譯而設(shè)計的;而其他更普通的在譯成數(shù)據(jù)結(jié)構(gòu)的技術(shù)叫(quoting,將在本章的結(jié)尾“代碼”一節(jié)討論。模塊塊(看這一章后面的“命名空間和模塊”一節(jié)。個模塊沒有顯式命名,那么源文件的名字,第一個字母大寫就是它的名字(F#module。關(guān)鍵字有兩種操作模式:一種是整個源文件中modulebeginend。為了包裝模塊定義,可以嵌ThirdModule嵌套在SecondModule中://createatoplevelmodule//createafirstmodulemoduleFirstModule=letn=//createasecondmodulemoduleSecondModule=letn=//createathird//nestedinsidethesecondmoduleThirdModule=letn=在F#交互模式中,不能使用沒有等號的module關(guān)鍵字;當(dāng)使用沒有等號的module關(guān)F#F#module就會出錯;但是,仍可以在F#交互模式中使用有等號的module來創(chuàng)建子模塊。。識符之間不會面的例子中,三個模塊中都定義了標(biāo)識符n;下面的例子演示如何每個模塊中的標(biāo)識符n:。//unpackthevaluesdefinedineachmoduleletx=ModuleDemo.FirstModule.nlety=letz=這一段代碼會編譯成一個.NET類,連同值一起,成為這個類中的方法和字段。在第十四章,會有有關(guān)F#的模塊與其他.NET編程語言相比較的細(xì)節(jié)。命名空間命名空間名是用點(diǎn)分隔的幾部分字符串組成。例如,F(xiàn)#提供一個模塊,名叫List,.NETBCL提供一個類,名字也叫List;但是,這并沒有命名,因為,F(xiàn)#模塊在命名空間.FSharp下,而BCL類在命名空間System.Collections.Generic下。命名空間使編譯的代碼保持獨(dú)立,因此,不允許在F#交互中使用,因為,這毫無意義。同。也可以顯式地為模塊定義命名空間,用namespace指令。例如,下面的定義:modulenamespaceStrangelights.BeginningmoduleModuleDemo因此,用namespace指令把子模塊放在命名空間中。例如://putthefileinanamespacenamespaceStrangelights.Beginning//createafirstmodulemoduleFirstModule=letn=//createasecondmodulemoduleSecondModule=letn=//createathird//nestedinsidethesecondmoduleThirdModule=letn=代碼編譯以后,從外部來看,n的第一個實例要用標(biāo)識符Strangelights.Foundation.FirstModule.n來,而不能僅僅是FirstModule.n。把幾說,前面示例中的FirstModule和SecondModule也可以放在單獨(dú)名空間中;但是,不能單獨(dú)名空間中SecondModule和ThirdModule,因為,ThirdModule是嵌套在SecondModule中的,不能為ThirdModule單獨(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類的實例。就像下面的代碼:open//createaninstanceofadictionaryletwordCountDict=newGeneric.Dictionary<string,使用部分限定名,比如Generic.Dictionary,可能會使程序難于。因此,應(yīng)該這樣使用,要么是名字加完整名空間,要么只有名字。可以F#的模塊,但不能非F#庫函數(shù)中的類。如果模塊,就可以用簡稱其中的值和類型。例如,下面的示例引用兩個模塊:.FSharp.Math.PhysicalConstants和.FSharp.Math.SI,這兩個都在FSharp.PowerPackc,光的速度,實現(xiàn)的著名等式e=mc2:openopen//letm=//lete=m*(c*有些認(rèn)為,應(yīng)該謹(jǐn)慎使用直接模塊,因為這樣會很難找到標(biāo)識符的。注意,F(xiàn)#庫函數(shù)的許多模塊不能直接事實上模塊通??梢苑譃閮深愐徊糠质鞘褂萌Q的,另一部分是直接的;大多數(shù)模塊是使用全稱的,很少直接的。通常的原因是,直接模塊,會使你直接使用其中的運(yùn)算符。下面的例子自定義了一個模塊,包含了三個等號的運(yùn)算符,然后,這個模塊,使用這個運(yùn)算符://moduleofoperatorsmoduleMyOps=//checkequalityviahashcodelet(===)xy=x.GetHashCode()=//opentheMyOpsmoduleopenMyOps//usethetripleequaloperatorletequal=1===1letnEqual=1===同名模塊或類中的值,只要值的名字不同就行。在圖6-1中,可以看到了命名空間BCLArrayF#Array6-1VisualStudio方法。對于在F#中創(chuàng)建的模塊,只需要給這個模塊一個別名。模塊別名的語法,關(guān)鍵字module,加標(biāo)識符,加等號,加想要應(yīng)用別名名空間或模塊的名字。下面的例子為命名空間.FSharp.Collections.Array3定義了別名//giveanaliastotheArray3moduleArrayThreeD=//createanmatrixusingthemodulealiasletmatrix=ArrayThreeD.create333函數(shù)類型表示文件(SignatureFiles)SignatureFiles,](private-i任何出現(xiàn)在函類型表示件中的定都公開(puic)的,使用塊的任何都能;沒有出現(xiàn)函數(shù)類表示文中的定都私有的能在模塊建函數(shù)型表示.fsimli;還必須為VisualStudio中,函數(shù)類型表示文件必須放在解決方案資源管理器(SolutionExplorer)中的源Lib.fs//defineafunctiontobeexposedletfunkyFunctionx=x+":keepit//defineafunctionthatwillbehiddenletnotSoFunkyFunctionx=x+1現(xiàn)在,假設(shè)想創(chuàng)建的庫只想funkyFunction,而不想notSoFunkyFunction,應(yīng)該//exposeavalfunkyFunction:string->fsc-aLib.fsi結(jié)果,程序集名為Lib.dll,類名為Lib,公開函數(shù)名為funkyFunction,私有函數(shù)名為私有和內(nèi)部(PrivateandInternal)letF#還有另法控制值或類型的可見性,即,把關(guān)鍵字private或internal直接放在let綁定的后面,使綁定成為私有或內(nèi)部。比如:letprivateaPrivateBinding="Keepthisprivate"letinternalaInternalBinding="Keepthisinternal"private使值或類型只在當(dāng)前模塊中可見,關(guān)鍵字internal程序集中可見。關(guān)鍵字private和internal的意思大體上與C#中的相同。關(guān)鍵字internal專門對F#是不可見的。下面的示例使用關(guān)鍵字internal隱藏聯(lián)合類型://ThistypewillnotvisibleoutsidethecurrentassemblytypeinternalMyUnion=|Stringof|TwoStringsofstring*privateinternal隱藏對象的成員,只需要簡單地把關(guān)鍵字private和internal直接放在關(guān)鍵字member的后面就行了。比如:namespaceStrangelight.BeginningtypeThing()=memberprivatex.PrivateThing()=memberx.ExternalThing()=[]privateinternal(interfacefiles,也提供了相似的功能,必須在兩個地方更新定義。對于兩次更新的問題,我通常寧可使用關(guān)鍵字private和塊之前,通過例子可能更容易理解。假設(shè)有一個源文件ModuleOne.fs,代碼如下:module//sometexttobeusedbyanothermodulelettext="sometext"module//printoutthetextdefinedinModuleOneprintfn"ModuleOne.text:%s"ModuleOne.text這兩個模塊用下面令可以編譯成功fscModuleOne.fsModuleTwo.fs-o但是,用下面令編譯,就會出錯fscModuleTwo.fsModuleOne.fs-oModuleTwo.fs(3,17):error:FS0039:Thenamespaceormodule'ModuleOne'isnot之所以出錯,是因為在ModuleTwo的定義中用到了ModuleOne,因此,在命令行中,ModuleOne必須出現(xiàn)在ModuleTwo的前面,否則,ModuleOne就不會在ModuleTwo的作VisualStudio(SolutionExplorer)中文件出現(xiàn)VisualStudio菜單改變文件的順序(如圖6-2。6-2VisualStudio大體來說,F(xiàn)計算,在頂層的所有語句或所有頂層的do語句都會執(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這可能出乎你的想像,但是,記住,這很重要,因為ModuleOne不是最后傳遞給編譯器的里,ModuleOnemodule//thiswillbeprintedwhenthe//membernisfirstaccessedprintfn"Thisisthethirdandfinal"letn=ModuleTwo.fs:moduleModuleTwo//thesetwolinesshouldbeprintedprintfn"Thisisthefirstline"printfn"Thisisthesecond"http://functiontoaccessModuleOneletfunct()=printfn"%i"ModuleOne.nfscModuleOne.fsModuleTwo.fs-oThisisthefirstlineThisisthesecondThisisthethirdandfinal中的最后,要有一條頂層語句[不知道對不對?]。條件編譯(OptionalCompilation)]它可能很方便,例如,如果你想讓生成(build)的庫函數(shù)支持.NET1.1和2.0,并且,想包括額外的值和類型,以利用2.0版中的新功能。然而,不應(yīng)該這一技術(shù),要很慎F#defineFLAG#ifFLAG也可以使用VisualStudio的生成配置菜單(參見圖6-3。6-3VisualStudio注意,使用VisualStudio,可以添加兩個預(yù)定義的開關(guān)[不是編譯符號]:DEBUG和TRACE。這是兩個專門的開關(guān),因為它們會影響某些框架的方法。比如:通過調(diào)用Assert.Debug的斷言,只在定義了DEBUG符號時才觸發(fā)。是作為F#交互的代碼(如果你打算編譯這段代碼,需要引用System.Winows.Fors.dll:open//definealetform=new//dosomethingdifferentdependingifwe're//asacompiledprogramofasascript#ifCOMPILEDApplication.Runform類似的,F(xiàn)#交互定義了符號INCTIVE,因此,可以用來測試是否在交互模式。F#(//)開始,直到這一行的結(jié)束。如下面的示//thisisasingle-line在F#中,單選注釋通常是首選,因為這個字符的輸入更快、更容易。(*thisisacomment(*thisisa通常,多行注釋只用于臨時注釋掉大段代碼。與其他大多數(shù)語言不同,F(xiàn)#釋,與O'Caml的注釋相同。如果多行注釋不封閉,會編譯出錯。文檔注釋(Doc文檔注釋,可以從源文件中提取注釋,以XML或HTML的格式。這是非常有用的,因為,這樣程序員就可以瀏覽代碼的注釋而不看源代碼。對于API的提供者尤其方便,因為可以只和緊隨其后的值、類型相關(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然后,就可以用各種工具來處理這個XML文件,比如,Sandcastle /Sandcastle),它可以把XML文件轉(zhuǎn)換成更可讀的格式。我發(fā)現(xiàn),把Sandcastle和Sandcastle幫助文件(http: 成工具對有些記號的支持不好比如泛型和聯(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)作條件編譯符號(optionalcompilationsflags)看待。放在注釋(*F#F#*)之間的所有代碼將常的注釋出現(xiàn),因此,將會被忽略。類似地,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語句的特征的,且是編譯時的特征。因此,譯成特征或特性。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)記一個類型和它所有的成員都是obsolete。openSystemtypeOOThing=valstringThing:stringnew()={stringThing=""}memberx.GetTheString()=x.string_thing如果打算在自己的程序中使用WinForms或WindowsPresentationFoundation(WPF)apartmentSTAThreaddoopenopenSystem.Windows.Formsletform=newForm()doSystem.Reflection.MemberInfoIsDefinedGetCustomAttributes這些方法在大多數(shù)用于反映的對象上是可用的,包括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下面的代碼定義一個標(biāo)識符,并用于//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)])下面的示例了一個函數(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)很相似處理也很簡單就是對它進(jìn)行模式匹配下面的示例定義一個函數(shù)interpretInt,anint”:open//afunctiontointerpretverysimplequotationsletinterpretIntexp=matchexp|Value(x,typ)whentyp=typeof<int>->printfn"%d"(x:?>|_->printfn"notan//te

溫馨提示

  • 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論