C++ 程式設計/程式語言/比較/D
The D 程式語言,由 Digital Mars 內部開發,這是一家小型美國軟體公司,也以生產 C 編譯器(隨著時間的推移而被稱為 Datalight C 編譯器、Zorland C 和 Zortech C)、第一個 Windows C++ 編譯器(最初稱為 Zortech C++,後來更名為 Symantec C++,現在稱為 Digital Mars C++ (DMC++) 和各種實用程式(例如支援 MFC 庫的 Windows IDE)而聞名。
該語言最初由 Walter Bright 設計,自 2006 年以來,Andrei Alexandrescu 和其他貢獻者也參與了該語言的開發。雖然 D 起源於 C++ 的重新設計,並且主要受 C++ 的影響,但 D 並不是 C++ 的變體。D 重新設計了一些 C++ 特性,並受到其他程式語言(如 Java、C# 和 Eiffel)中使用的概念的影響。因此,D 是一種不斷發展的開源系統程式語言,支援多種程式設計正規化。
它支援過程式、泛型、函式式和麵向物件正規化。最值得注意的是,它提供了非常強大但易於使用的編譯時超程式設計功能。
它旨在提供效率、控制和建模能力的實用組合,同時兼顧安全性,並提高程式設計師的生產力。它的另一個目標是易於初學者使用,並在經驗豐富的程式設計師需要時提供高階功能。
D 在 x86 和 x86_64 上正式支援 Windows、Linux、OSX 和 FreeBSD。對其他平臺(Android、iOS 和 Solaris)和硬體(ARM、MIPS 和 Power-PC)的支援正在進行中。
有 3 個可用於生產的編譯器:DMD、GDC 和 LDC。
- DMD 是參考實現。另外兩個編譯器共享 DMD 的前端。它提供了非常快的編譯速度,在開發時很有用。
- GDC 使用 GCC' 的後端進行程式碼生成。它與 GNU 工具鏈很好地整合。
- LDC 使用 LLVM' 的後端。它可以與 LLVM 工具鏈的其他部分很好地整合。
D 可以直接連結到 C 和 C++(*) 靜態和共享庫,而無需任何包裝器或額外開銷(與 C 和 C++ 相比)。支援 C++ 平臺特定 ABI 的子集(例如 GCC 和 MSVC)
- C++ 命名修飾約定,如名稱空間、函式名等
- C++ 函式呼叫約定
- C++ 虛擬函式表佈局,用於單一繼承
通常,D 在每個平臺上使用平臺連結器(例如,在 Linux 上使用 ld.bfd、ld.gold 等),唯一的例外是 Windows,預設情況下使用 Optlink。MSVC link.exe 也受支援,但必須先下載 Windows SDK。
C/C++ 程式設計師會發現一些新特性:
- 內省設計 - 可以設計模板類或結構體,在編譯時檢查其模板引數以獲得不同的功能,然後適應它們。例如,可組合的分配器設計可以檢查父分配器是否提供重新分配,並有效地委派給它,或者回退到使用 malloc() 和 free() 實現重新分配,或者根本不提供它。在編譯時執行此操作的好處是,所述分配器的使用者可以知道他是否應該使用 reallocate(),而不是遇到神秘的執行時錯誤。
- 真正的模組
- 宣告和匯入的順序(在 C++ 中稱為
#include)無關緊要。無需預先宣告任何內容。您可以重新排列內容,而不改變含義。 - 更快的編譯 - C++ 的編譯模型本質上 很慢。此外,像 DMD 這樣的編譯器還有進一步的最佳化。
- 更強大的條件編譯,無需預處理器
pure函式 - 無副作用的函式,允許進行內部變異。- 不變性 - 保證宣告為不可變的變數可以從多個執行緒安全地訪問(無需鎖定和競爭條件)。
- 契約式設計
- 通用函式呼叫語法 (UFCS) - 允許像這樣呼叫自由函式
void copyTo(T)(T[] src, T[] dst):sourceArray.copyTo(destinationArray) - 內建單元測試
- 垃圾回收(可選)
scope控制流語句(在 C++ 中使用ScopeGuardidiom 部分模擬)
一等公民
- 動態陣列
int[] array; //declare empty array variable
array ~= 42; //append 42 to the array; array.equals([ 42 ]) == true
array.length = 5; //set the length to 5; will reallocate if needed
int[] other = new int[5]; // declare an array of five elements
other[] = 18; // fill the array with 18; other.equals([18, 18, 18, 18, 18]) == true
array[] = array[] * other[]; //array[i] becomes array[i] * other[i]
array[$ - 1] = -273; // set the last element to -273; when indexing an array the $ context variable is translated to array.length
int[] s = array[2 .. $]; // s points to the last 3 elements of array (no copying occurs).
- Unicode 字串
string s1 = "Hello "; // array of immutable UTF8 chars
immutable(char)[] s2 = "World "; // `s2` has the same type as `s1`
string s3 = s1 ~ s2; // set `s3` to point to the result of concatenating `s1` with `s2`
char[] s4 = s3.dup; // `s4` points to the mutable array "Hello World "
s4[$-1] = '!'; // change the last character in the string
s4 ~= "<-> Здравей, свят!"; // append Cyrillic characters that don't fit in a single UTF-8 code-unit
import std.conv : to;
wstring ws = s4.to!wstring; //convert s4 to an array of immutable UTF16 chars
foreach (dchar character; ws) // iterate over ws; 'character' is an automatically transcoded UTF32 code-point
{
import std.stdio : writeln; // scoped selective imports
character.writeln(); //write each character on a new line
}
您可以在 dpaste.dzfl.pl - 專注於 D 的線上編譯器和協作工具 中找到一個可執行的示例。
- 關聯陣列
struct Point { uint x; uint y; } // toHash is automatically generated by the compiler, if not user provided
Point[string] table; // hashtable string -> Data
table["Zero"] = Point(0, 0);
table["BottomRight"] = Point(uint.max, uint.max);
- 巢狀函式
- 閉包(C++11 添加了 lambda 函式,但透過引用捕獲變數的 lambda 函式不允許退出建立它們的函式)。
- 內部類
- 預處理器
- 具有非虛擬解構函式的多型型別
- 多型值型別 - 在 D 中,
struct是沒有繼承和虛擬函式支援的值型別,而class是支援繼承和虛擬函式的引用型別。 - 多重繼承 - D 類僅提供 Java 和 C# 風格的多重介面實現。相反,對於程式碼重用,D 更傾向於組合、
mixin和alias this
有關更多詳細資訊,請參閱 D 程式設計 書籍。