posts - 5,comments - 0,trackbacks - 0
          什么是 D 語(yǔ)言?D 是一種通用的系統(tǒng)和應(yīng)用編程語(yǔ)言。它是比 C++ 更高級(jí)的語(yǔ)言,同時(shí)還保持了生成高效代碼以及直接訪問(wèn)操作系統(tǒng)API和硬件的能力。D 很適合于編寫(xiě)從中等規(guī)模到那些由團(tuán)隊(duì)合作完成、數(shù)百萬(wàn)行代碼規(guī)模的各種程序。D 易于學(xué)習(xí),為編程者提供了很多便利,并且適用各種野心勃勃的編譯器優(yōu)化技術(shù)。

          D 不是腳本語(yǔ)言,也不是一種解釋型語(yǔ)言。它不需要虛擬機(jī)、宗教、或者高于一切的哲學(xué)。它是給實(shí)際的編程者使用的實(shí)際的語(yǔ)言,它幫助編程者快速、可靠的完成易于維護(hù)、易于理解的代碼。

          D 是數(shù)十年來(lái)實(shí)現(xiàn)多種語(yǔ)言編譯器的經(jīng)驗(yàn)的積累,是用那些語(yǔ)言構(gòu)造大型工程的嘗試的積累。D 從那些語(yǔ)言(主要是 C++ )那里獲得了靈感,并將 使用經(jīng)驗(yàn)和現(xiàn)實(shí)世界中的實(shí)用性來(lái)馴服它。 D Man

          為什么是 D ?

          確實(shí),為什么?有誰(shuí)需要另一種編程語(yǔ)言?

          自 從 C 語(yǔ)言被發(fā)明以來(lái),軟件工業(yè)走過(guò)了一段很長(zhǎng)的路。許多新的概念被加入了 C++ 中,但同時(shí)維護(hù)了同 C 的向后兼容性,包括兼容了原始設(shè)計(jì)中的所有的弱點(diǎn)。有很多修正這些弱點(diǎn)的嘗試,但是兼容性是最大的困擾。同時(shí),C 和 C++ 都在不斷引入新的特性。這些新特性必須被小心的加入到現(xiàn)有的結(jié)構(gòu)中,以免重寫(xiě)舊的代碼。最終的結(jié)果十分復(fù)雜—— C 標(biāo)準(zhǔn)將近 500 頁(yè),C++ 標(biāo)準(zhǔn)大概有 750 頁(yè)!C++ 實(shí)現(xiàn)起來(lái)既困難又代價(jià)高昂,造成的結(jié)果就是各種實(shí)現(xiàn)之間都有差別,因此很難寫(xiě)出完全可以移植的 C++ 代碼。

          C++ 程序員傾向于使用語(yǔ)言中的孤島來(lái)編程,也就是說(shuō),他們傾向于十分精通語(yǔ)言中的某個(gè)特性而避免使用其他特性。盡管代碼通常在編譯器之間是可移植的,但在程序 員之間移植就不那么容易了。C++ 的一個(gè)長(zhǎng)處是它支持很多根本上不同的編程風(fēng)格——但從長(zhǎng)遠(yuǎn)來(lái)看,互相重復(fù)和互相沖突的風(fēng)格會(huì)給開(kāi)發(fā)帶來(lái)妨礙。

          C++ 在標(biāo)準(zhǔn)庫(kù)而不是語(yǔ)言核心中實(shí)現(xiàn)了可改變大小的數(shù)組和字符串拼接等。不在語(yǔ)言核心中實(shí)現(xiàn)這些功能造成了幾種不太理想的結(jié)果。

          是否能把 C++ 的能力釋放、重新設(shè)計(jì)并重鑄到一門簡(jiǎn)單、正交并實(shí)用的語(yǔ)言中呢? 這種語(yǔ)言是否能做到易于正確實(shí)現(xiàn),并使編譯器有能力有效地生成高度優(yōu)化的代碼呢?

          現(xiàn) 代編譯器技術(shù)已經(jīng)取得了很大的進(jìn)步,有些原來(lái)用作原始編譯技術(shù)的補(bǔ)充的語(yǔ)言特性已經(jīng)可以被忽略了(一個(gè)這樣的例子是 C 語(yǔ)言中的‘register’關(guān)鍵字,一個(gè)更為微妙的例子是 C 中的宏預(yù)處理程序)。我們可以依賴現(xiàn)代編譯器的優(yōu)化技術(shù)而不是使用語(yǔ)言特性(如同原始的編譯器所做的那樣)來(lái)獲得可以接受的代碼質(zhì)量。

          D的主要目標(biāo)

          • 通過(guò)加入已經(jīng)被證明的能夠提高生產(chǎn)力的特性、調(diào)整語(yǔ)言特性以避免常見(jiàn)但耗費(fèi)精力的bug的出現(xiàn),至少減少軟件開(kāi)發(fā)成本10%。
          • 是代碼易于在編譯器之間、在機(jī)器之間、在操作系統(tǒng)之間移植。
          • 支持多種編程范式,也就是至少支持命令式、結(jié)構(gòu)化、面向?qū)ο蠛头缎途幊谭妒健?
          • 對(duì)于熟悉 C 或者 C++ 的人來(lái)說(shuō),學(xué)習(xí)曲線要短。
          • 提供必要的低級(jí)訪問(wèn)能力。
          • 要使 D 的編譯器從根本上易于實(shí)現(xiàn)(相對(duì)于 C++ 來(lái)說(shuō))。
          • 要同本機(jī)的 C 語(yǔ)言應(yīng)用程序二進(jìn)制接口相兼容。
          • 語(yǔ)法要做到上下文無(wú)關(guān)。
          • 對(duì)編寫(xiě)國(guó)際化的應(yīng)用程序提供便利的支持。
          • 同時(shí)支持契約式編程和單元測(cè)試方法論。
          • 能夠構(gòu)建輕量級(jí)的、獨(dú)立的程序。

          從C/C++保留而來(lái)的特征

          粗看上去 D 就像 C 和 C++ 。這樣一來(lái)學(xué)習(xí)以及將代碼移植到 D 就很容易。從 C/C++ 轉(zhuǎn)向 D 應(yīng)該很自然。程序員不必從頭學(xué)起。

          使用 D 并不意味著程序員會(huì)如 Java 或者 Smalltalk 那樣被嚴(yán)格的限制在某一個(gè)運(yùn)行時(shí) vm (虛擬機(jī))上。D 沒(méi)有虛擬機(jī),編譯器直接生成可連接的目標(biāo)文件。D 如同 C 那樣被直接連接到操作系統(tǒng)。通常那些你熟悉的工具如 make 同樣適用于 D 的開(kāi)發(fā)。

          • D 將很大程度上保留 C/C++ 的 觀感 。它將使用相同的代數(shù)語(yǔ)法,絕大多數(shù)的相同表達(dá)式和語(yǔ)句形式,以及總體的結(jié)構(gòu)。
          • D 程序既可以采用 C 風(fēng)格的 函數(shù)和數(shù)據(jù) 范式,也可以采用 C++ 風(fēng)格的 面向?qū)ο?/b> 范式,或者它們兩者的混合。
          • 編譯/鏈接/調(diào)試 的開(kāi)發(fā)模型將會(huì)被繼承下來(lái),但是把 D 編譯成為字節(jié)碼然后解釋執(zhí)行也不會(huì)有任何問(wèn)題。
          • 異常處理 越來(lái)越多的使用經(jīng)驗(yàn)顯示,異常處理是比 C 傳統(tǒng)的“出錯(cuò)代碼/全局errno變量”模型更為高級(jí)的錯(cuò)誤處理模型。
          • 運(yùn)行時(shí)類型識(shí)別 C++ 部分地實(shí)現(xiàn)了這個(gè)功能,而 D 更進(jìn)一步。對(duì)運(yùn)行時(shí)類型識(shí)別的完全支持將使垃圾收集運(yùn)行的更好,會(huì)使調(diào)試器的功能更強(qiáng),會(huì)使對(duì)自動(dòng)持久化的支持更好等等。
          • D 維持了同 C 調(diào)用慣例 的兼容。這樣就能夠使 D 程序直接訪問(wèn)操作系統(tǒng)的 API 。程序員有關(guān)現(xiàn)有 API 和編程范例的知識(shí)和經(jīng)驗(yàn)可以繼續(xù)在使用 D 時(shí)使用而只需付出很少的努力。
          • 運(yùn)算符重載 D 支持對(duì)運(yùn)算符的重載,這樣就可以用用戶定義的類型擴(kuò)展由基本類型構(gòu)成的類型系統(tǒng)。
          • 模板 模板是實(shí)現(xiàn)范型編程的一種手段。其他的手段包括使用宏或者采用協(xié)變數(shù)據(jù)類型。使用宏已經(jīng)過(guò)時(shí)了。協(xié)變類型很直接,但是低效且缺少類型檢查。C++ 模板的問(wèn)題是它們太復(fù)雜,同語(yǔ)言的語(yǔ)法不和諧,還有各種各樣的類型轉(zhuǎn)換和重載規(guī)則,等等。D 提供了一種簡(jiǎn)單得多的使用模板的方法。
          • RAII(資源獲得即初始化) RAII 技術(shù)是編寫(xiě)可靠軟件的重要方法之一。
          • Down and dirty 編程 D 將保留 down-and-dirty 編程的能力,而不用采用別的語(yǔ)言編寫(xiě)的外部模塊。在進(jìn)行系統(tǒng)編程時(shí),有時(shí)需要將一種指針轉(zhuǎn)換成另一種指針,或者使用匯編語(yǔ)言。D 的目標(biāo)不是避免 down and dirty 編程,而是減少在進(jìn)行普通程序設(shè)計(jì)時(shí)對(duì)它們的需要。

          廢棄的特征

          • 對(duì) C 的源碼級(jí)兼容性。保留對(duì) C 的源碼級(jí)兼容的擴(kuò)展已經(jīng)有了(C++ 和 Objective-C)。在這方面的進(jìn)一步工作受制于大量的遺留代碼,已經(jīng)很難對(duì)這些代碼進(jìn)行什么重大的改進(jìn)了。
          • 對(duì) C++ 的鏈接兼容性。C++ 的運(yùn)行時(shí)對(duì)象模型太復(fù)雜了——如果要較好的支持它,基本上就是要求 D 編譯器變成一個(gè)完整的 C++ 編譯器了。
          • C 預(yù)處理程序。宏處理是一種擴(kuò)展語(yǔ)言的簡(jiǎn)單方法,它可以給語(yǔ)言加入某些語(yǔ)言本不支持的(對(duì)于符號(hào)調(diào)試器不可見(jiàn)的)特征。條件編譯、使用 #include 分層的文本、宏、符號(hào)連接等,本質(zhì)上構(gòu)成了兩種難以區(qū)分兩種語(yǔ)言的融合體,而不是一種語(yǔ)言。更糟的是(或許是最好的),C 預(yù)處理程序是一種十分原始的宏語(yǔ)言。是停下來(lái)的時(shí)候了,看看預(yù)處理程序是用來(lái)做什么的,并將這些功能直接設(shè)計(jì)到語(yǔ)言內(nèi)部。
          • 多重繼承。它是一種擁有飽受爭(zhēng)議的價(jià)值的復(fù)雜特征。它很難用一種高效的方式實(shí)現(xiàn),而且在編譯器實(shí)現(xiàn)它時(shí)很容易出現(xiàn)各種 bug 。幾乎所有的 MI 的功能都能夠通過(guò)使用單根繼承加接口和聚集的方式實(shí)現(xiàn)。而那些只有 MI 才能支持的功能并不能彌補(bǔ)它帶來(lái)的副作用。
          • 名字空間。當(dāng)鏈接獨(dú)立開(kāi)發(fā)的代碼時(shí),可能會(huì)發(fā)生名字的沖突,名字空間就是解決這個(gè)問(wèn)題的一種嘗試。模塊的概念更簡(jiǎn)單并且工作得更好。
          • 標(biāo)記名字空間。這是 C 的一個(gè)糟糕的特征,結(jié)構(gòu)的標(biāo)記名稱位于一個(gè)同其它符號(hào)不同的符號(hào)表中。C++ 試圖合并標(biāo)記名字空間和正常的名字空間,但同時(shí)還要維持對(duì)遺留 C 代碼的向后兼容性。造成的結(jié)果是不可打印。
          • 前 向聲明。C 編譯器在語(yǔ)義上只知道什么東西實(shí)在詞法上位于當(dāng)前狀態(tài)之前的。C++ 進(jìn)行了一點(diǎn)點(diǎn)擴(kuò)展,類中的成員可以依賴于它之后聲明的類成員。D 更進(jìn)一步,得到了一個(gè)合情合理的結(jié)論,前向聲明根本就沒(méi)有存在的必要。函數(shù)可以按照一種自然的順序定義,不用再像 C 那樣為了避免前向聲明而采用常用的從里到外的順序定義。
          • 包含文件。造成編譯器運(yùn)行緩慢的原因之一是編譯每個(gè)編譯單元時(shí)都需要重新解析數(shù)量巨大的頭文件。包含文件的工作應(yīng)該采用導(dǎo)入到符號(hào)表中的方式來(lái)完成。
          • 在堆棧上創(chuàng)建對(duì)象實(shí)例。在 D 中,所有的類都通過(guò)引用來(lái)訪問(wèn)。這樣就不需要復(fù)制構(gòu)造函數(shù)、賦值運(yùn)算符、復(fù)雜的析構(gòu)語(yǔ)義以及同異常處理中的堆棧展開(kāi)的相互作用。內(nèi)存資源由垃圾收集程序負(fù)責(zé)釋放,其他資源通過(guò)使用 D 的 RAII 特征釋放。
          • 三字節(jié)碼和雙字節(jié)碼。Unicode 是未來(lái)。
          • 預(yù)處理程序。現(xiàn)代語(yǔ)言不應(yīng)該需要文本處理,它們應(yīng)該只需要符號(hào)處理。
          • 非 虛成員函數(shù)。在 C++ 中,由累得設(shè)計(jì)者決定一個(gè)函數(shù)是否應(yīng)該是虛函數(shù)。在子類中重寫(xiě)一個(gè)函數(shù)而忘記在父類中將其更新為虛函數(shù)是一個(gè)常見(jiàn)的(并且非常難以發(fā)現(xiàn)的)編碼錯(cuò)誤。將所 有成員函數(shù)設(shè)置為虛函數(shù),并由編譯器來(lái)判斷函數(shù)是否被重寫(xiě)、并由此將沒(méi)有被重寫(xiě)的函數(shù)轉(zhuǎn)換為非虛函數(shù)的做法更為可靠。
          • 任意長(zhǎng)度的位字段。位字段是一種復(fù)雜、低效并且很少用到的特征。
          • 支持16位計(jì)算機(jī)。D 從不考慮混合使用遠(yuǎn)/近指針和其它所有用于聲稱好的16位代碼的機(jī)制。D 語(yǔ)言的設(shè)計(jì)假設(shè)目標(biāo)機(jī)器至少擁有32位的平坦內(nèi)存空間。D 將能夠被毫無(wú)困難的移植到64位架構(gòu)上。
          • 對(duì)編譯遍數(shù)的互相依賴。在 C++ 中,需要一個(gè)符號(hào)表和各種的預(yù)處理程序命令才能成功的解析一個(gè)源文件。這樣就使預(yù)解析 C++ 源碼變得不可能,并且使編寫(xiě)代碼分析程序和語(yǔ)法制導(dǎo)的編輯器的過(guò)程十分難以正確實(shí)現(xiàn)。
          • 編譯器的復(fù)雜性。通過(guò)降低實(shí)現(xiàn)的復(fù)雜度,這就更有可能出現(xiàn)多個(gè)正確的實(shí)現(xiàn)。
          • ‘.’和‘->’之間的區(qū)別。這種區(qū)別其實(shí)很沒(méi)有必要。‘.’運(yùn)算符完全可以起到‘->’所起的指針解引用的作用。

          D 適合于?

          • 經(jīng)常使用 lint 或者類似的代碼分析工具以期在編譯之前減少 bug 的程序員。
          • 將編譯器的警告級(jí)別調(diào)到最高的人和那些告訴編譯器把警告作為錯(cuò)誤的人。
          • 不得不依靠編程風(fēng)格規(guī)范來(lái)避免常見(jiàn)的 C bug 的編程部門經(jīng)理們。
          • 認(rèn)定 C++ 面向?qū)ο缶幊趟手Z的功能由于 C++ 太復(fù)雜而不能達(dá)到的人。
          • 沉溺于 C++ 強(qiáng)大的表達(dá)力但是被顯式內(nèi)存管理和查找指針 bug 折磨得精疲力盡的人。
          • 需要內(nèi)建的測(cè)試和驗(yàn)證機(jī)制的項(xiàng)目。
          • 開(kāi)發(fā)百萬(wàn)行規(guī)模的程序的團(tuán)隊(duì)。
          • 認(rèn)為語(yǔ)言應(yīng)當(dāng)提供足夠的特征以避免顯式處理指針的程序員。
          • 編寫(xiě)數(shù)值運(yùn)算程序的程序員。D 擁有眾多直接支持?jǐn)?shù)值計(jì)算的特征,例如直接提供了復(fù)數(shù)類型和擁有確定行為的 NaN 和無(wú)窮大。(這些都被加進(jìn)了最新的 C99 標(biāo)準(zhǔn),但是沒(méi)有加進(jìn) C++ 中。)
          • D 的詞法分析程序和解析程序完全互相獨(dú)立,并且獨(dú)立于語(yǔ)義分析程序。這意味著易于編寫(xiě)簡(jiǎn)單的工具來(lái)很好地處理 D 源碼而不用編寫(xiě)一個(gè)完整的編譯器。這還意味著源碼可以以記號(hào)的形式傳遞個(gè)某個(gè)需要它的程序。

          D 不適合于?

          • 現(xiàn)實(shí)一點(diǎn)說(shuō),沒(méi)人會(huì)把上百萬(wàn)行的 C 或 C++ 程序用 D 重新寫(xiě)一遍,因?yàn)?D 不直接兼容 C/C++ 源代碼,D 并不適合于遺留程序。(但是,D 對(duì)遺留的 C API 提供了很好的支持。)
          • 非常小的程序——腳本或解釋性語(yǔ)言如 Python、DMDScript 或者 Perl 更適合于這種情況。
          • 作為第一門程序設(shè)計(jì)語(yǔ)言—— Basic 或者 Java 更適合于初學(xué)者。對(duì)于中級(jí)到高級(jí)的程序員來(lái)說(shuō),D 是他們優(yōu)秀的第二門語(yǔ)言。
          • 語(yǔ) 言純粹主義者。D 是一門實(shí)用的語(yǔ)言,它的每個(gè)特征都是為這個(gè)目的服務(wù)的,D 并沒(méi)有想成為一門“完美”的語(yǔ)言。例如,D 擁有可以基本上避免在日常任務(wù)中使用指針的結(jié)構(gòu)和語(yǔ)義。但是 D 仍然支持指針,因?yàn)橛袝r(shí)我們需要打破這條規(guī)則。類似地,D 保留了類型轉(zhuǎn)換,因?yàn)橛袝r(shí)我們需要重寫(xiě)類型系統(tǒng)。

          D 的主要特征

          本節(jié)列出了一些更有趣的 D 的特征。

          面向?qū)ο缶幊?/h3>

          D 的面向?qū)ο筇煨詠?lái)自于類。采用的繼承模型時(shí)單根繼承加接口。Object 類為與繼承體系的最頂端,所以所有的類都實(shí)現(xiàn)了一個(gè)通用的功能集合。類通過(guò)引用的方式實(shí)例化,所以不需要用于在異常后進(jìn)行清理工作的復(fù)雜代碼。

          運(yùn)算符重載

          類可以通過(guò)重載現(xiàn)有的運(yùn)算符擴(kuò)展類型系統(tǒng)來(lái)支持新類型。例如創(chuàng)建一個(gè) bignumber class ,然后重載 +、-、* 和 / 運(yùn)算符,這樣大數(shù)類就可以使用普通的代數(shù)運(yùn)算語(yǔ)法了。

          生產(chǎn)力

          模塊

          源文件同模塊是一一對(duì)應(yīng)的。D 不再“包含”帶有聲明的文件的文本,而是“導(dǎo)入”該模塊。不用擔(dān)心多次導(dǎo)入一個(gè)模塊,也不用再把頭文件用 #ifndef/#endif 或者 #pragma once 包起來(lái)了。

          聲明 vs 定義

          C++ 的函數(shù)和類通常需要聲明兩次——聲明位于 .h 頭文件中,定義位于 .c 源文件中。這個(gè)過(guò)程易于出錯(cuò)而且冗長(zhǎng)繁瑣。顯然,應(yīng)該只需要程序員編寫(xiě)一次,而由編譯器提取出聲明信息并將它導(dǎo)入到符號(hào)表中。這正是 D 所做的。

          示例:

          class ABC	{	    int func() { return 7; }	    staticint z = 7;	}	int q;	
          不再需要單獨(dú)定義成員函數(shù)、靜態(tài)成員、外部聲明之類的,也不需要像這樣煩人的語(yǔ)法:
          int ABC::func() { return 7; }	int ABC::z = 7;	extern int q;	
          注記:當(dāng)然,在 C++ 中,瑣碎的函數(shù)如 { return 7; } 也可以直接寫(xiě)在聲明處,但是復(fù)雜的函數(shù)就不行了(uframer:雖然從語(yǔ)法上說(shuō)依然是可以的,但會(huì)違反 C++ 接口和實(shí)現(xiàn)分離的原則。)。另外,如果有前向引用的話,就必須保證已經(jīng)聲明了被引用的那個(gè)函數(shù)一個(gè)原型。下面的代碼在 C++ 中是不合法的:
          class Foo	{	    int foo(Bar *c) { return c->bar; }	};	class Bar	{	  public:	    int bar() { return 3; }	};	
          但是等價(jià)的 D 代碼就可以正常工作:
          class Foo	{	    int foo(Bar c) { return c.bar; }	}	class Bar	{	    int bar() { return 3; }	}	
          D 函數(shù)是否被在線化取決于優(yōu)化程序的設(shè)置。

          未完待續(xù)...

          posted on 2007-01-05 10:19 zxc 閱讀(211) 評(píng)論(0)  編輯  收藏

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 故城县| 宜兰市| 九龙县| 禹城市| 自贡市| 江陵县| 额敏县| 常德市| 嘉峪关市| 略阳县| 登封市| 神农架林区| 张家港市| 拉孜县| 鄯善县| 黄骅市| 镇宁| 屯留县| 宜兰市| 和田市| 普定县| 龙州县| 定南县| 崇文区| 革吉县| 天长市| 武安市| 新兴县| 包头市| 米脂县| 绩溪县| 贡嘎县| 泗阳县| 徐闻县| 台南市| 武乡县| 龙海市| 夏邑县| 汕头市| 白朗县| 石河子市|