1. 程式人生 > 程式設計 >重新認識 D語言 —— 基礎篇

重新認識 D語言 —— 基礎篇

程式語言的興盛往往隨著全球資訊科技產業方向而變化,同樣也會因為跟不上節奏而沒落。 D 語言曾經興盛過,也隨著資訊科技發展而頹廢過,但最終我們很高興的看到它又帶著強烈的自信開始復甦,希望通過本文讓現代電腦科學工作者進一步瞭解這門具有獨特魅力的程式語言。

作者:鄒佳慶、張雪平

引言

D 語言是一門語法相當優雅的編譯型語言,自 1999 年釋出至今已發展了 20 年,它既擁有 Java 那樣強大的表現力,又具有 C++ 相當的效能,本來是一門未來相當明朗的語言,但是當年因為 2.x 版本破壞性升級導致社群大量核心開發者將其放棄。

2010 年,伴隨著 Andrei Alexandrescu 新書《The D Programming Language》的出版,D 語言又變得活躍起來,D 語言 2.0 的特性變得穩定,執行庫與標準庫的分離,解決了 D 語言 1.0 時期標準庫之爭的問題。

2011 年,D 語言的開發遷移到了 Github,在有了更好的程式碼管理和 bug 跟蹤方式之後,參與到 D 語言編譯器、執行庫和標準庫開發的人員也有了明顯的增加。次年,D 語言 1.0 版本停止更新,開發者全力投入到 2.0 的開發。

2014 年,D 語言編譯器前端程式碼的許可協議變更為更加寬鬆的 Boost 許可。在 2017 年,編譯器所有程式碼最終都使用了 Boost 許可。在解決編譯器原始碼許可問題之後,D 語言在開源社群中變得更加開放,並順利合併進入了 GCC 9.x。

直到 2015 年,D 語言社群進一步恢復活力,基於包管理的構建方式開始成熟,大量的開發庫開始湧現並應用到實際專案中。目前,已註冊專案庫達 1 千 6 百多個。

DLang Packages

重新燃起希望的 D 語言在版本釋出的規劃上非常穩健,直至今日來說每兩個月都可以保證一個大版本的釋出。平均每個版本的開發者數量都有超過 50 個核心貢獻者,最近的 2.087.0 更是達到了 62 位核心開發者的貢獻。

程式語言的戰爭異常慘烈,本文希望通過介紹,讓開發者重新來瞭解一下 D 語言,認識到 D 語言其實是一門能力強大的語言,並且它可以用於不同的場景,生態也在不斷髮展完善中。

第一部分:D 語言主要特點

D 語言是在吸取 C++ 遇到的各種教訓基礎上設計出來的,擁有與之類似的程式設計風格,許多概念與 C 或 C++ 都是相通的。不過,D 語言也有自己的一些特點,如支援閉包、匿名函式、編譯時函式執行、支援垃圾回收等。具體來講,D 語言擁有以下幾個主要特點:

面向物件程式設計

D 語言允許定義類和介面。像 Java 一樣,D 語言的繼承模型是單類繼承和多介面繼承。所有的類都有一個根類 Object。D 語言的類和介面都是引用型別,而結構是值型別,且不允許繼承。

函式語言程式設計

D 語言像 C++ 一樣,允許在類或結構外單獨定義函式。它還提供了各種不可變資料型別、匿名函式和閉包、UFCS(統一函式呼叫語法)等特性來更好地支援函式語言程式設計。

泛型程式設計

D 語言允許定義模型型別,也支援直接定義模板類和模板函式。模板允許巢狀定義,模板方法甚至允許遞迴呼叫。通過模板約束可以實現模板型別過載。模板引數支援不定個數型別。除此以外,模板引數型別還支援自動推導。

超程式設計

D 語言裡的純函式不會對全域性變數產生任何影響,因此可以在編譯時直接呼叫。藉助 static if、static foreach、mixin 等語句,可以編寫在編譯時執行的程式碼,動態生成程式碼,滿足快速定製應用功能的需求。

安全記憶體

預設支援基於垃圾回收的記憶體管理方式,從而讓程式設計變得更簡單,記憶體變得安全,程式變得更穩定。除此之外,也可以根據需要對關鍵的記憶體資源選擇手動管理方式。藉助 scope 語句,可以很好地控制記憶體資源申請和釋放點。D 語言內部有一套核心的型別定義和實現,它是 D 語言的一個子集,也被稱作 SafeD,用於保護記憶體的安全。

模組化程式設計

D 語言的每一個原始檔都被定義為一個模組(module),原始檔之間的依賴即體現了模組之間的依賴。同一目錄下的多個模組可以組成一個包(package)。基於模組的程式碼讓專案的邏輯變得更加清晰,也為專案的快速構建和編譯提供了支援。

其他語言互動

D語言的ABI與C語言完全相容,因此它也具有很好的與其他語言互動的能力,如與 CC++Objective-C 等語言進行互動程式設計。D 語言甚至支援直接嵌入彙編語言,部分效能關鍵的程式碼可以直接使用匯編語言來實現。D 語言的 BetterC 特性是 D 語言的一個子集,能完全去除 GC 依賴,並以更好 C 語言的方式來代替 C 語言程式設計,它能勝任 C 語言做的絕大部分工作。在 Windows 平臺下,可以使用 COM 介面實現與其他語言的互動。

基於包的應用構建

這個不屬於 D 語言本身特性,但是在 D 語言的開發生態裡,這是一種很非常重要和便捷的 D 語言應用構建方式。dub 是 D 語言的應用構建工具,它可以很好地管理應用包之間的依賴關係,快速地構建出 D 語言應用。

除了上述特點,D 語言還提供了許多其他特性,如內建關聯陣列、單元測試、內聯彙編、內嵌檔案等,這些特性讓 D 語言成為了一門功能強大的語言。

第二部分:與其它語言的簡要對比

D 語言與 Java 相比

眾所周知 Java 對工業化架構的設計非常棒,遠超越 C++、Golang 等語言,能與 Java 相提並論的只有 C#,在研究中我們發現 D 同樣具備工業化的特性,而且不需要那麼龐雜的虛擬機器器開發環境,D 的效能比起 Java 來說好的非常明顯,而且整合 C、C++ 庫的時候也非常方便,而 Java 想整合 C、C++ 就需要非常麻煩的 jni 對去接。畢竟 D 語言是名副其實的系統級開發語言,D 語言在面向物件方面並不像 Java 那樣強制每個檔案都是物件,而更像 C++ 那樣擁有一個 main() 函式作為程式入口。

示例程式碼

import std.stdio;

void main()
{
    writeln("Hello world!");
}
複製程式碼

D 語言與 C++ 相比

說到效能,C++ 一直佔據服務端高效能的首選,但是 D 的效能與 C++ 相比幾乎打成平手,但效率可以 3~5 倍於 C++。當然 D 與 C 語言各種庫整合同樣方便,因為 D 語言是二進位制與 C、C++ 相容的,語法更像是 C++ 的超級升級版,D 在對 hashMap 操作時效能比 C++ 還要高,而且只要是掌握 C++ 的人可以沒有任何門檻地使用 D 語言。

示例程式碼

import std.stdio;
void main()
{
    foreach(i; 1..10)
    {
        writeln(i);
    }
}
複製程式碼

D 語言與 PHP 相比

PHP 是服務端指令碼語言佔有率最高的語言,PHP 的優勢就是簡單,無需引入什麼包就可以使用語言本身的所有函式,但是也就是這樣 PHP 的效能一直沒有明顯改進,雖然說 PHP 7.x 的出現讓 PHP 的效能提升了 2.x 倍,但是那只是和非常慢的 PHP 5.x 相比而已,與編譯型語言相比還是相差太多。PHP 有非常明顯的短板,比如不支援多執行緒、長連線不友好、弱型別、跨語言 RPC 協議支援不穩定、部署需要 PHP 執行環境等,而 D 語言具備 C++ 可實現的所有功能,包括內嵌彙編,開發效率上來講與 PHP 相比只是多了個強型別的概念,而 D 語言標準庫也提供 to 方法讓你非常方便地進行各種型別的轉換。

示例程式碼

import std.stdio : writeln;
import std.conv : to; 

void main()
{
    int i = 10000;
    string s = "Is string ";

    s ~= i.to!string;    // PHP 使用點連線兩個字串,而 D 語言使用波浪線連線兩個字串

    writeln(s);    // 輸出結果 Is string 10000
}
複製程式碼

D 語言可替代 C 語言

前陣子有一篇文章比較火,有一位 i3 核心開發者在文章中說到,D 才是真正替代 C 的首選語言,他認為 D 二進位制與 C、C++ 完全相容所以可直接使用這兩個語言的二進位制庫,D 甚至可以用 dpp 專案直接 #include 語法引入 *.h 檔案,作者同時也說到為什麼 C 的替代者不是 Rust 和 Golang,有興趣的同學可以自行了解原文《D as a C Replacement》。

D as a C Replacement

gcc 整合 D 語言編譯支援

這是一個非常大的進步,在近期釋出的 gcc 9.1 大版本中整合了 DLang 全新的編譯器前端也就是 gdc,現在整個社群有更多開發者對 D 專案進行推進,也有更多人在使用 D 完成之前 C/C++ 的工作。

第三部分:D 語言主要應用

作為一門支援 GC 的系統語言,D 語言已被許多公司採納和應用,其中不乏像 Facebook、eBay 這樣的大公司。D 的應用涉及了遊戲、Web 應用、GUI 應用、作業系統、編譯器、嵌入式、科學計算與教育等多個領域。

遊戲開發

Remedy 公司已成功地用 D 語言將一款 3A 遊戲 Quantum Break 移植到了 XBox One 和 Windows 10 平臺。另外,有純 D 語言實現的 3D 遊戲引擎 Dash 和 D 語言遊戲開發工具庫 gfm

Web 框架

程式語言在 Web 服務端框架非常重要,有好用的框架可以讓整個語言充滿活力,就像 Java 有一個 Spring Framework 框架,PHP 有一個 laravel 框架,Python 擁有一個 Django,而 Ruby 擁有 Rails,所以既然是構建服務端應用 DLang 也同樣擁有一個代表性的框架 Hunt Framework

資料庫操作

資料庫操作是大部分應用專案都不可或缺的一個基本操作,操作方式主要有兩種:編寫 SQL 指令碼和 ORM

直接操作資料庫的 D 語言開庫有 ddbc / hunt-database 等,支援的資料庫包括 MySQL、PostgreSQL 和 SQLite 等。其中,新版本的 hunt-database 的底層驅動庫已從繫結 C 語言的方式升級為了直接使用 D 語言實現,減少了對第三方庫的依賴。

採用 ORM 方式的 D 語言開庫有 hibernated / hunt-entity 等。其中,hunt-entity 借鑑了 Java JPA 和 spring-data-jpa 的概念,工業化程度高,操作合理並且易於維護。

微服務相關

hunt-service 是基於 gRPC 協議的分散式 RPC 伺服器與客戶端庫,很容易使用,也非常方便與 hunt-framework 整合構建微服務架構。

neton 是基於 raft 演演算法的分散式服務發現註冊應用服務。

GUI 應用

其實 D 語言的推出比較早,所以 GTK 的整合非常完整,眾所周知 gtk 官方的 vala 語言也大量借鑑了 D 的語言設計,所以 gtkd 能夠非常方便的構建客戶端應用,官方也有開發者推出了新的教程站點非常棒:gtkDcoding | Simple examples of how to use GtkD to build GUI applications(gtkdcoding.com/)

此外,純 D 語言實現的跨平臺 GUI 庫 dlangui 也有不俗的表現,有一個 DLangIDE 就是基於它實現的。更多 GUI 庫可以參考這裡

系統應用

在編譯器方面,DMD 前端已實現自舉。在作業系統方面,有 PowerNexTrinix 等系統嘗試。編譯器 LDC 甚至允許在更多的系統平臺下進行應用開發,如支援基於 ARM 和 MIPS 架構的嵌入式系統、Android 系統等。

科學計算

現在使用 D 語言可以方便的進行科學計算,mir 是其中的佼佼者,它對多維陣列計算提供了優秀的支援,效能超越了許多數值計算庫,達到商業水平。

結語

簡單來說,D 語言是一門在各個領域具有優勢的程式語言,同時它當前的生態也在不斷髮展,本文希望通過簡單的介紹,讓開發者重新認識 D 語言。如果你還不瞭解 D 語言,讀完本文,希望你對它產生興趣;如果你此前有聽說過 D 語言,讀完本文,希望你能重新認識它;如果你對 Web 開感興趣,請持續關注本系列接下來的 Web 應用篇。

參考資料

en.wikipedia.org/wiki/D_(pro…

dlang.org/overview.ht…

en.wikipedia.org/wiki/Unifor…

dlang.org/articles/sa…

dlang.org/orgs-using-…

dlang.org/areas-of-d-…

dconf.org/2016/talks/…