D語言
维基百科,自由的百科全书
| D | |
|---|---|
| 编程范型: | 多範型 |
| 面市時間: | 1999 |
| 設計者: | Walter Bright |
| 最近釋出日期: | 1.022 (穩定版)/ 2007年10月1日[1] |
| 型態系統: | 強型態,靜態 |
| 主要實作產品: | DMD, GDC |
| 啟發語言: | C, C++, C#, Java, Eiffel |
D 語言是由 Digital Mars 公司的 Walter Bright 所開發的物件導向、指令式、多範型系統程式設計語言。D 語言起源自 C++,並受到 C++ 很大的影響,不過 D 語言並不是 C++ 的變種。D 語言對 C++ 的部分特性重新設計,並受到其它程式語言觀念的影響,如 Java、C# 以及 Eiffel。2007年1月2日釋出 1.0 穩定版本。實驗性版本 2.0 釋出於 2007年1月17日。
Walter Bright 本身是 Symantec C++ 編譯器的作者。
目录 |
[编辑] 特性
D 的設計來自實際的 C++ 用法的經驗教訓,而不是從理論的角度。儘管 D 用到很多 C/C++ 觀念,D 同時也廢除了某部分,因此 D 並不完全向後相容 C/C++ 原始碼。D 加入了 C++ 的功能,也實作了契約式設計(design by contract)、單元測試、真正的模組性、自動化記憶體管理(垃圾回收)、第一類陣列(first class array)、關聯陣列、動態陣列、陣列切片、嵌套函式(巢狀函式)、內部類別、閉包的限制形式、匿名函式、編譯時期函式執行、惰性計算以及革新的模板語法。D 保有 C++ 的性能以進行低階程式設計,並加入完整的內聯組譯器支援。C++ 的多重繼承改以 Java 單繼承與介面混合的風格取代。D 的宣告、語句和表達式語法幾乎和 C++ 一樣。
內聯組譯器(inline assembler)象徵著 D 和 Java、C# 等應用程式語言的不同。內聯組譯器讓程式員輸入機器特定的組合語言碼,如同標準 D 代碼—通常由系統程式員使用的技術,以存取處理器的低階功能,直接以硬體下的界面執行程式,如作業系統以及驅動程式。
D 內建支援文件註解,不過目前為止,只有 Digital Mars 實作版本有提供文件產生器。
[编辑] 程式設計範型
D 支援三種主要的程式設計範型—指令式、物件導向以及元程式設計。
[编辑] 指令式
指令式程式設計幾乎和 C 一樣。函式、資料、語句、宣告以及表達式的運作就如同 C 一般,且可直接存取 C 執行時期程式庫。
[编辑] 物件導向
在 D 裡面的物件導向程式設計,是以單繼承分層結構,配合所有類別衍伸自類別物件為基礎。多重繼承可使用界面(界面很像 C++ 的抽象類別)。
[编辑] 元程式設計
以模板組合、編譯時期函式執行、多元組以及字串混合來支援元程式設計。
[编辑] 記憶體管理
記憶體通常以垃圾回收管理,不過當這些物件超出作用域時,可立即結束指定的物件。還是可以使用重載運算子 new 和 delete,以及簡單的直接呼叫 C 的 malloc 和 free 以進行顯示的記憶體管理。垃圾回收可禁用個別的物件或事件,以健全整個程式,如果在記憶體管理上有更多的控制,則更為理想。當垃圾回收在程式中有所不足時,手冊還提供許多如何實作不同的高度最佳化記憶體管理方案的範例。
[编辑] 與其它系統的相互作用
支援 C 的應用程式二進制介面(ABI),以及 C 的基本和衍伸型態,就能直接存取現有的 C 代碼以及程式庫。C 的標準函式庫也是 D 標準的一部分。除非你使用非常清楚的命名空間,它可以稍微散亂的存取,因為它散佈遍及於 D 模組—不過純粹的 D 標準函式庫也通常夠用,除非要與 C 代碼接合。
並未完整支援 C++ 的 ABI,儘管 D 可以存取寫給 C ABI 的 C++ 代碼,且可存取 C++ COM(元件物件模型)代碼。D 語法分析器了解外部(C++)呼叫約定,以連結 C++ 物件,不過它只實作在目前的實驗性 D 2.0。
[编辑] D 2.0
D 2.0,D 的分支版本包含實驗性特性,釋出於2007年1月17日。其中一部分特性包括支援強制常數正確性(const-correctness),以及有限的支援連結以 C++ 編寫的代碼。
[编辑] 實作
儘管 D 仍處於開發階段,自 2007 年 1 月 的 1.0 版本,語言已不再定期的變更。目前的設計工作實質上已經停止,且新釋出版本的著重在解決現存的錯誤。版本 1.0 不完全相容舊版本的語言和編譯器。官方編譯器由 Walter Bright 定義語言本身。
- DMD 編譯器:Digital Mars D 編譯器,由 Walter Bright 編寫的官方 D 編譯器。編譯器前端的授權許可在 Artistic License 和 GNU GPL 兩者;前端的原始碼連同編譯器執行碼一起發佈。編譯器的後端則是私有的。
- GDC:D 1.0 編譯器,以 DMD 編譯器前端,以及 GCC 後端所組成。
[编辑] 問題和爭議
[编辑] 運算子重載
D 運算子重載在一定程度上不如 C++ 強大。簡單的例子是 opIndex,它不允許返回引用。這使像是 obj[i] = 5; 的賦值不可能存在。D 的解決方法是 opIndexAssign 運算子,它只用於這種特殊情況。此外,C++ 返回參考的方法允許返回型態的重載賦值運算子的用法。這在目前的 D 還不可能做到。D 2.0 將會引入 opIndexLvalue 修正 - 類似運算子重載和 opIndexAssign。
[编辑] 低功的結構
結構在 D 之中是一種樸素舊式資料的型態,不過也可像變數一樣包含方法。這對有意輕量化的建構而言相當實用,如矩陣或向量,這些不需要完整的 D 類別功能(以及體積)。然而,D 結構沒有建構子和解構子。建構子可用靜態 opCall 運算子部分取代,不過它沒有適合的解構子等價物。此外,結構不允許繼承,這會是有益的設計,如詭異循環模板模式(curiously recurring template pattern)的使用。
[编辑] 標準函式庫中缺乏功能
D 的標準函式庫稱作 Phobos,且時常被認為過分簡單。tango 專案編寫另一個標準函式庫試圖修正這一部分,不過 phobos 和 tango 目前由於不同的物件類別實作(導致垃圾回收困難)而互不相容。存在兩種事實上的標準函式庫可能導致更大的問題,部分軟體使用 phobos,而其它軟體使用 tango。
[编辑] 缺乏明確的目標
D 經常限於「修正並改進的 C++」。這會導致過分強調功能,這起因於加入新功能只是因為他們認為有用。舉個例子,關聯陣列可簡單的以標準函式庫實現。
[编辑] 未完成對共享/動態函式庫的支援
Unix 的 ELF 共享函式庫使用 GDC 編譯器支援到某個程度。在 Windows 系統中,目前還不支援 DLL。因此現階段不可能編寫插件。不像 C++,經由 C 函式傳送的 D 物件將不能運作,因為這將會與垃圾回收器產生衝突。
[编辑] 範例
[编辑] 範例 1
這個範例程式會輸出它自己的命令列參數。main 函式是 D 程式的進入點,args 是表示為字串陣列的命令列參數。在 D 語言裡的字串是一個字元陣列,以 char[] 表示。新版本中定義 string 為 char[] 的別名,不過別名定義必須與舊版本相容。
import std.stdio; // 以使用 writefln() alias char[] string; // 以相容舊的編譯器;新的編譯器中已隱含定義 int main(string[] args) { foreach(i, a; args) writefln("args[%d] = '%s'", i, a); return 0; }
foreach 語法可迭代所有的集合,在本例中,它從 args 陣列生成索引(i)和值(a)的序列。索引 i 和值 a 的型態會從 args 陣列的型態推斷。
[编辑] 範例 2
本例使用關聯陣列建立更複雜的資料結構。
import std.stdio; // 以使用 writefln() alias char[] string; // 以相容舊的編譯器;新的編譯器中已隱含定義 int main(string[] args) { // 宣告以字串鍵和字串陣列作為資料的關聯陣列 string[] [string] container; // 將人們加入到容器中,並讓他們攜帶一些項目 container["Anya"] ~= "scarf"; container["Dimitri"] ~= "tickets"; container["Anya"] ~= "puppy"; // 迭代容器中所有的人 //Iterate over all the persons in the container foreach (string person, string[] items; container) display_item_count(person, items); return 0;//完成 } void display_item_count(string person, string[] items) { writefln(person, " is carrying ", items.length, " items."); }
[编辑] 範例 3
本例繁多的註解顯示出 D 語言與 C++ 的不同之處,以及仍然保留的方面。
#!/usr/bin/dmd -run /* 支援 sh 風格的 script 語法! */ /* D 語言的 Hello World * 進行編譯: * dmd hello.d * 或進行最佳化: * dmd -O -inline -release hello.d * 或產生文件: * dmd hello.d -D */ import std.stdio; // 參照常用的 I/O 例行工作。 alias char[] string; // 以相容舊的編譯器;新的編譯器中已隱含定義 int main(string[] args) { // 'writefln' (寫入-格式化-行,Write-Formatted-Line) 即型態安全的「printf」 writefln("Hello World, " // 自動連結的字串文字 "Reloaded"); // 字串即字元的動態陣列「char[]」,別名為「string」 // 自動的型態推斷,以及內建的 foreach foreach(argc, argv; args) { auto cl = new CmdLin(argc, argv); // 支援 OOP writefln(cl.argnum, cl.suffix, " arg: %s", cl.argv); // 使用者定義的類別屬性。 delete cl; // 垃圾回收或顯示的記憶體管理——由你自己選擇 } // 巢狀結構、類別和函式 struct specs { // 所有的變數會在執行時期自動初始化為 0 int count, allocated; // 不過你可選擇避開陣列的初始化 int[10000] bigarray = void; } specs argspecs(string[] args) // 可選用的(內建)函式契約。 in { assert(args.length > 0); // 內建 assert } out(result) { assert(result.count == CmdLin.total); assert(result.allocated > 0); } body { specs* s = new specs; // 不需要「->」 s.count = args.length; // 「length」屬性是元素的數量。 s.allocated = typeof(args).sizeof; // 原生型態內建的屬性 foreach(arg; args) s.allocated += arg.length * typeof(arg[0]).sizeof; return *s; } // 內建字串和普通的字串操作,例如「~」是連結。 string argcmsg = "argc = %d"; string allocmsg = "allocated = %d"; writefln(argcmsg ~ ", " ~ allocmsg, argspecs(args).count,argspecs(args).allocated); return 0; } /** * 儲存單獨命令列參數 */ class CmdLin { private { int _argc; string _argv; static uint _totalc; } public: /** * 物件的建構子。 * 參數: * argc = 參數的序列計數。 * argv = 參數內文。 */ this(int argc, string argv) { _argc = argc + 1; _argv = argv; _totalc++; } ~this() // 物件的解構子 { // 本例中不做任何事。 } int argnum() // 屬性,可返回參數數目 { return _argc; } string argv() // 屬性,可返回參數內文 { return _argv; } wstring suffix() // 屬性,可返回序數後綴 { wstring suffix; // 內建 Unicode 字串(UTF-8,UTF-16,UTF-32) switch(_argc) { case 1: suffix = "st"; break; case 2: suffix = "nd"; break; case 3: suffix = "rd"; break; default: // 'default' is mandatory with "-w" compile switch. suffix = "th"; } return suffix; } /** * 靜態屬性,如同在 C++ 或 Java 中, * 適用於類別物件,而不是實體。 * 返回:己加入的命令列參數總數。 */ static typeof(_totalc) total() { return _totalc; } // 類別不變量,任何方法在執行之後,這些必須為真。 invariant () { assert(_argc > 0); assert(_totalc >= _argc); } }
[编辑] 範例 4
本例顯示出一部分 D 語言強大的編譯時期特性。
/* * D 語言裡的模板比 C++ 的要更加強大。 * 在此可以看到使用 static if(D 的編譯時期條件建構)簡單的建構出階乘模板。 */ template Factorial(ulong n) { static if( n <= 1 ) const Factorial = 1; else const Factorial = n * Factorial!(n-1); } /* * 這裡有一個正規的函式,可完成同樣的計算。 * 注意它們有多麼的相似。 */ ulong factorial(ulong n) { if( n <= 1 ) return 1; else return n * factorial(n-1); } /* * 終於,我們可以計算我們的階乘。注意,我們不需要去 * 明確的指定我們的常數的型態:編譯器有足夠的智能為 * 我們填充空白,因為它早已知道賦值中右手邊的型態。 */ const fact_7 = Factorial!(7); /* * 這是編譯時期函式評估的範例:普通函式可用於常數、 * 編譯時期表達式,假若它們滿足一定的條件。 */ const fact_9 = factorial(9); /*在此我們可以看到多麼強大的 D 模板:我們使用 * std.metastrings.Format 模板完成型態安全的 printf * 資料格式化,並使用 message pragma 顯示計算結果。 */ import std.metastrings; pragma(msg, Format!("7! = %s", fact_7)); pragma(msg, Format!("9! = %s", fact_9)); /* * 完成任務後,我們可以強制停止編譯。這樣的程式需是 * 從未實際編譯成可執行檔! */ static assert(false, "My work here is done.");
[编辑] 參閱
[编辑] 參考資料
[编辑] 外部連結
- Digital Mars: D 程式語言(官方網站)
- D 在开放式目录中
- DSource,D 語言的開放原始碼社群。
- Dprogramming.com,視窗化程式庫 DFL 的首頁。
- Wiki4D,「D 語言的維基頁」
- gdc,GCC 的 D 語言前端
- 電腦語言評測遊戲
- D 文件的維基頁
- D 語言特性列表
- Walter Bright 介紹 D 語言的影片
- Ddbg - Win32 D 除錯器
- DWin - D語言庫
- DLogo - D語言按鈕, 廣告欄
- SciTE4D - D語言編輯器
- D語言中國社區, D語言入門,D語言GUI介紹等
- D語言中文討論區
- D Programming Language簡介
|
|
|
|---|---|
| 工业编程语言 | A+ - ActionScript - Ada - 汇编语言 - B - Brainfuck - COBOL - Curl - D - Eiffel - Erlang - FORTRAN - IronPython - Java - JavaScript - JScript - Jython - LISP - Lua - SCILAB - MATLAB - MATHEMATICA - Nuva - Oberon - OCaml - Perl - PHP - PostScript - Powerbuilder - Python - R - REXX - Ruby - Self - Smalltalk - Tcl/Tk - C# - F# - J# - Microsoft Visual C# |
| C/C++语言 | C - C++ - Turbo C++ - Borland C++ - C++ Builder- C++/CLI - Objective-C - Microsoft Visual C++ |
| BASIC语言 | BASIC - BASICA - GW-BASIC - QBASIC - QuickBASIC - True BASIC - Turbo BASIC - PowerBASIC - DarkBASIC -ETBASIC Visual Basic .NET - Visual Basic - VBScript - VBA |
| Pascal/Delphi语言 | Pascal語法:(Pascal - Turbo Pascal - Object Pascal - Free Pascal) Pascal+Delphi語法:(Delphi) |
| GPU用著色器語言 | Cg - GLSL - HLSL |
| 学术编程语言 | APL/J - Clean - Haskell - Logo - ML - Prolog - Scheme - SAC |
| 資料庫相關编程语言 | Clipper - Visual FoxPro - SQL - SQL預存程序 |
| 其他编程语言 | ALGOL - Forth - Modula-2/Modula-3 - MUMPS - PL/I - Simula |

