跳轉到內容

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 工具鏈的其他部分很好地整合。
與 C 和 C++ 互動
[編輯 | 編輯原始碼]

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。

D 中缺少的 C 和 C++ 特性
[編輯 | 編輯原始碼]

C/C++ 程式設計師會發現一些新特性:

  • 內省設計 - 可以設計模板類或結構體,在編譯時檢查其模板引數以獲得不同的功能,然後適應它們。例如,可組合的分配器設計可以檢查父分配器是否提供重新分配,並有效地委派給它,或者回退到使用 malloc() 和 free() 實現重新分配,或者根本不提供它。在編譯時執行此操作的好處是,所述分配器的使用者可以知道他是否應該使用 reallocate(),而不是遇到神秘的執行時錯誤。
  • 真正的模組
  • 宣告和匯入的順序(在 C++ 中稱為 #include)無關緊要。無需預先宣告任何內容。您可以重新排列內容,而不改變含義。
  • 更快的編譯 - C++ 的編譯模型本質上 很慢。此外,像 DMD 這樣的編譯器還有進一步的最佳化。
  • 更強大的條件編譯,無需預處理器
  • pure 函式 - 無副作用的函式,允許進行內部變異。
  • 不變性 - 保證宣告為不可變的變數可以從多個執行緒安全地訪問(無需鎖定和競爭條件)。
  • 契約式設計
  • 通用函式呼叫語法 (UFCS) - 允許像這樣呼叫自由函式 void copyTo(T)(T[] src, T[] dst)sourceArray.copyTo(destinationArray)
  • 內建單元測試
  • 垃圾回收(可選)
  • scope 控制流語句(在 C++ 中使用 ScopeGuard idiom 部分模擬)

一等公民

  • 動態陣列
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 函式不允許退出建立它們的函式)。
  • 內部類
C++ 中缺少的 D 特性
[編輯 | 編輯原始碼]
  • 預處理器
  • 具有非虛擬解構函式的多型型別
  • 多型值型別 - 在 D 中,struct 是沒有繼承和虛擬函式支援的值型別,而 class 是支援繼承和虛擬函式的引用型別。
  • 多重繼承 - D 類僅提供 Java 和 C# 風格的多重介面實現。相反,對於程式碼重用,D 更傾向於組合、mixinalias this

有關更多詳細資訊,請參閱 D 程式設計 書籍。

華夏公益教科書