D 語言的模組化、開發效率、可讀性以及其它一些特性使其非常適合用於協同軟體的開發。 -- Lawrence Aberba
本文導航-模組化能力 …… 05%
-開發效率 …… 20%
-可讀性和可維護性 …… 32%
-方便 …… 48%
-選擇 …… 84%
-更多 …… 89%
編譯自: https://opensource.com/article/17/5/d-open-source-software-development作者: Lawrence Aberba
譯者: ucasFL
D 語言的模組化、開發效率、可讀性以及其它一些特性使其非常適合用於協同軟體的開發。
D 程式設計語言[1]是一種靜態類型的通用程式設計語言, 它具有和 C 語言類似的語法, 能夠編譯為本地代碼。 許多理由使得它很適合用於開源軟體發展, 下面講到的是其中一些理由。
模組化能力在大多數情況下, 當你有一個好的想法, 你可以完全按照你的內心所想的方式通過代碼來實現它。 然而, 有的時候, 你不得讓你的想法向代碼妥協, 而不是通過模組化代碼來適應想法。 D 語言支援多種程式設計範式[2], 包括函數式風格、命令式、物件導向、元程式設計、併發(演員模式), 這些全都和諧共存。
通過使用範本[3], 可以生成額外的 D 代碼並在編譯的過程中把它編排進去, 你可以把這些代碼描述成編譯器生成代碼的一種模式。 這是一種非常有用的設計演算法, 無需把它們綁定到任何特定的類型。 由於模版的通用性, 就很容易生成平臺無關的代碼。 通過將範本與條件編譯[4]結合, 跨平臺的應用變得更加容易實現, 也更容易接受來自使用不同作業系統的開發者的貢獻。 有了這一點, 一個程式師可以通過很少的代碼, 利用有限的時間實現很多東西。
range[5] 已經深度集成到了 D 語言中, 相對於具體實現, 它抽象出容器元素(比如陣列、關聯陣列和鏈表等)是如何訪問的。
大多數開源軟體的代碼貢獻者都是基於有限的時間志願工作的。 D 語言能夠極大的提高開發效率, 因為你可以用更少的時間完成更多的事情。 D 的範本和 range 使得程式師在開發通用代碼和可複用代碼時效率更高, 但這些僅僅是 D 開發效率高的其中幾個優勢。 另外一個主要的吸引力是, D 的編譯速度看起來感覺就像解釋型語言一樣, 比如 Python、JavaScript、Ruby 和 PHP, 它使得 D 能夠快速成型。
D 可以很容易的與舊的代碼進行對接,
void main()
{
writeln("Hello, World!");
}
D 語言的 Hello, World 演示
對於熟悉 C 語言的人來說, D 代碼很容易理解。 另外, D 代碼的可讀性很強, 即使是複雜的代碼。 這使得很容易發現錯誤。 可讀性對於吸引貢獻者來說也是很重要的, 這是開源軟體成長的關鍵。
在 D 中一個非常簡單但很有用的語法糖[13]是支援使用下滑線分隔數位, 這使得數位的可讀性更高。 這在數學上很有用:
int count = 100_000_000;double price = 20_220.00 + 10.00;
int number = 0x7FFF_FFFF; // 16 進制系統
ddoc[14] 是一個內建的工具, 它能夠很容易的自動根據代碼注釋生成文檔, 而不需要使用額外的工具。 文檔寫作、改進和更新變得更加簡單, 不具挑戰性, 因為它伴隨代碼同時生成。
Contract[15] 能夠檢查代碼的實現, 從而確保 D 代碼的行為能夠像期望的那樣。 就像法律契約的簽訂是為了確保每一方在協議中做自己該做的事情, 在 D 語言中的契約式程式設計, 能夠確保實現的每一個函數、類等如期望的那樣產生預期的結果和行為。 這樣一個特性對於錯誤檢查非常實用, 特別是在開源軟體中, 當多個人合作一個項目的時候。 契約是大項目的救星。D 語言強大的契約式程式設計特性是內建的,而不是後期添加的。契約不僅使得使用 D 語言更加方便,也減少了正確寫作和維護困難的頭痛。
方便協同開發是具有挑戰性的,因為代碼經常發生變化,並且有許多移動部分。D 語言通過支援在本地範圍內導入模組,從而緩解了那些問題:
// 返回偶數int[] evenNumbers(int[] numbers)
{
// "filter" and "array" are only accessible locally
import std.algorithm: filter;
import std.array: array;
return numbers.filter!(n => n%2 == 0).array;
}
對 filter 使用 ! 運算子是範本參數[16]的一個語法
上面的函數可以在不破壞代碼的情況下調用,因為它不依賴任何全域導入模組。像這樣實現的函數都可以在後期無需破壞代碼的情況下增強,這是協同開發的好東西。
通用函式呼叫語法(UFCS)[17]是 D 語言中的一個語法糖,它允許像調用一個物件的成員函數那樣調用常規函數。一個函數的定義如下:
void cook(string food, int quantity){
import std.stdio: writeln;
writeln(food, " in quantity of ", quantity);
}
它能夠以通常的方式調用:
string food = "rice";int quantity = 3;
cook(food, quantity);
通過 UFCS,這個函數也可以像下面這樣調用,看起來好像 cook 是一個成員函數:
string food = "rice";int quantity = 3;
food.cook(quantity);
在編譯過程中,編譯器會自動把 food 作為 cook 函數的第一個參數。UFCS 使得它能夠鏈起來常規函數,給你的代碼產生一種函數風格程式設計的自然感覺。UFCS 在 D 語言中被大量使用,就像在上面的 evenNumbers 函數中使用的 filter 和 array 函數那樣。結合範本、range、條件編譯和 UFCS 能夠在不犧牲方便性的前提下給予你強大的力量。
auto 關鍵字可以用來代替任何類型。編譯器在編譯過程中會靜態推斷類型。這樣可以省去輸入很長的類型名字,讓你感覺寫 D 代碼就像是在寫動態類型語言。
// Nope. Do you?VeryLongTypeHere variable = new VeryLongTypeHere();
// 使用 auto 關鍵字
auto variable = new VeryLongTypeHere();
auto name = "John Doe";
auto age = 12;
auto letter = 'e';
auto anArray = [1, 2.0, 3, 0, 1.5]; // type of double[]
auto dictionary = ["one": 1, "two": 2, "three": 3]; // type of int[string]
auto cook(string food) {...} // auto for a function return type
D 的foreach[18] 迴圈允許遍歷各種不同的底層資料類型的集合和 range:
foreach(name; ["John", "Yaw", "Paul", "Kofi", "Ama"]){
writeln(name);
}
foreach(number; [1, 2, 3, 4, 4, 6]) {...}
foreach(number; 0..10) {...} // 0..10 is the syntax for number range
class Student {...}
Student[] students = [new Student(), new Student()];
foreach(student; students) {...}
D 語言中內建的單元測試[19]不僅免除了使用外部工具的需要,也方便了程式師在自己的代碼中執行測試。所有的測試用例都位於可定制的 unittest{} 塊中:
int[] evenNumbers(int[] numbers){
import std.algorithm: filter;
import std.array: array;
return numbers.filter!(n => n%2 == 0).array;
}
unittest
{
assert( evenNumbers([1, 2, 3, 4]) == [2, 4] );
}
使用 D 語言的標準編譯器 DMD,你可以通過增加 -unittest 編譯器標誌把所有的測試編譯進可執行結果中。
選擇除了提供多種程式設計範例和功能特性外,D 還提供其他的選擇。它目前有三個可用的開源編譯器。官方編譯器 DMD 使用它自己的後端,另外兩個編譯器 GDC 和 LDC,分別使用 GCC 和 LLVM 後端。DMD 以編譯速度塊而著稱,而 LDC 和 GDC 則以在很短的編譯時間內生成快速生成機器代碼而著稱。你可以自由選擇其中一個以適應你的使用情況。
預設情況下,D 語言是採用垃圾收集[22]的記憶體分配方式的。你也可以選擇手動進行記憶體管理,如果你想的話,甚至可以進行引用計數。一切選擇都是你的。
更多在這個簡要的討論中,還有許多 D 語言好的特性沒有涉及到。我強烈推薦閱讀 D 語言的特性概述[23],這是隱藏在標準庫[24]中的寶藏,以及 D 語言的使用區域[25],從而進一步瞭解人們用它來幹什麼。許多組織已經使用 D 語言來進行開發[26]。最後,如果你打算開始學習 D 語言,那麼請看這本書 D 語言程式設計[27]。
(題圖:opensource.com)
via: https://opensource.com/article/17/5/d-open-source-software-development
作者:Lawrence Aberba[28] 譯者:ucasFL 校對:wxy
本文由 LCTT 原創編譯,Linux中國 榮譽推出
[1]: D 程式設計語言 - https://dlang.org/
[2]: 程式設計範式 - https://en.wikipedia.org/wiki/Programming_paradigm
[3]: 範本 - http://ddili.org/ders/d.en/templates.html
[4]: 條件編譯 - https://dlang.org/spec/version.html
[5]: range - http://ddili.org/ders/d.en/ranges.html
[6]: 陣列切片 - https://dlang.org/spec/arrays.html#slicing
[7]: 與 C 代碼進行自然地對接 - https://dlang.org/spec/interfaceToC.html
[8]: D 中也是可調用的 - https://dlang.org/spec/cpp_interface.html
[9]: Python - https://code.dlang.org/packages/pyd
[10]: Objective-C - https://dlang.org/spec/objc_interface.html
[11]: Lua - http://beza1e1.tuxen.de/into_luad.html
[12]: Fortran - http://www.active-analytics.com/blog/interface-d-with-c-fortran/
[13]: 語法糖 - https://en.wikipedia.org/wiki/Syntactic_sugar
[14]: ddoc - https://dlang.org/spec/ddoc.html
[15]: Contract - http://ddili.org/ders/d.en/contracts.html
[16]: 範本參數 - http://ddili.org/ders/d.en/templates.html
[17]: 通用函式呼叫語法(UFCS) - http://ddili.org/ders/d.en/ufcs.html
[18]: foreach - http://ddili.org/ders/d.en/foreach.html
[19]: 單元測試 - https://dlang.org/spec/unittest.html
[20]: Dub - http://code.dlang.org/getting_started
[21]: Dub package registry - https://code.dlang.org/
[22]: 垃圾收集 - https://dlang.org/spec/garbage.html
[23]: D 語言的特性概述 - https://dlang.org/comparison.html
[24]: 標準庫 - https://dlang.org/phobos/index.html
[25]: D 語言的使用區域 - https://dlang.org/areas-of-d-usage.html
[26]: 使用 D 語言來進行開發 - https://dlang.org/orgs-using-d.html
[27]: D 語言程式設計 - http://ddili.org/ders/d.en/index.html
[28]: Lawrence Aberba - https://opensource.com/users/aberba
契約是大項目的救星。D 語言強大的契約式程式設計特性是內建的,而不是後期添加的。契約不僅使得使用 D 語言更加方便,也減少了正確寫作和維護困難的頭痛。方便協同開發是具有挑戰性的,因為代碼經常發生變化,並且有許多移動部分。D 語言通過支援在本地範圍內導入模組,從而緩解了那些問題:
// 返回偶數int[] evenNumbers(int[] numbers)
{
// "filter" and "array" are only accessible locally
import std.algorithm: filter;
import std.array: array;
return numbers.filter!(n => n%2 == 0).array;
}
對 filter 使用 ! 運算子是範本參數[16]的一個語法
上面的函數可以在不破壞代碼的情況下調用,因為它不依賴任何全域導入模組。像這樣實現的函數都可以在後期無需破壞代碼的情況下增強,這是協同開發的好東西。
通用函式呼叫語法(UFCS)[17]是 D 語言中的一個語法糖,它允許像調用一個物件的成員函數那樣調用常規函數。一個函數的定義如下:
void cook(string food, int quantity){
import std.stdio: writeln;
writeln(food, " in quantity of ", quantity);
}
它能夠以通常的方式調用:
string food = "rice";int quantity = 3;
cook(food, quantity);
通過 UFCS,這個函數也可以像下面這樣調用,看起來好像 cook 是一個成員函數:
string food = "rice";int quantity = 3;
food.cook(quantity);
在編譯過程中,編譯器會自動把 food 作為 cook 函數的第一個參數。UFCS 使得它能夠鏈起來常規函數,給你的代碼產生一種函數風格程式設計的自然感覺。UFCS 在 D 語言中被大量使用,就像在上面的 evenNumbers 函數中使用的 filter 和 array 函數那樣。結合範本、range、條件編譯和 UFCS 能夠在不犧牲方便性的前提下給予你強大的力量。
auto 關鍵字可以用來代替任何類型。編譯器在編譯過程中會靜態推斷類型。這樣可以省去輸入很長的類型名字,讓你感覺寫 D 代碼就像是在寫動態類型語言。
// Nope. Do you?VeryLongTypeHere variable = new VeryLongTypeHere();
// 使用 auto 關鍵字
auto variable = new VeryLongTypeHere();
auto name = "John Doe";
auto age = 12;
auto letter = 'e';
auto anArray = [1, 2.0, 3, 0, 1.5]; // type of double[]
auto dictionary = ["one": 1, "two": 2, "three": 3]; // type of int[string]
auto cook(string food) {...} // auto for a function return type
D 的foreach[18] 迴圈允許遍歷各種不同的底層資料類型的集合和 range:
foreach(name; ["John", "Yaw", "Paul", "Kofi", "Ama"]){
writeln(name);
}
foreach(number; [1, 2, 3, 4, 4, 6]) {...}
foreach(number; 0..10) {...} // 0..10 is the syntax for number range
class Student {...}
Student[] students = [new Student(), new Student()];
foreach(student; students) {...}
D 語言中內建的單元測試[19]不僅免除了使用外部工具的需要,也方便了程式師在自己的代碼中執行測試。所有的測試用例都位於可定制的 unittest{} 塊中:
int[] evenNumbers(int[] numbers){
import std.algorithm: filter;
import std.array: array;
return numbers.filter!(n => n%2 == 0).array;
}
unittest
{
assert( evenNumbers([1, 2, 3, 4]) == [2, 4] );
}
使用 D 語言的標準編譯器 DMD,你可以通過增加 -unittest 編譯器標誌把所有的測試編譯進可執行結果中。
選擇除了提供多種程式設計範例和功能特性外,D 還提供其他的選擇。它目前有三個可用的開源編譯器。官方編譯器 DMD 使用它自己的後端,另外兩個編譯器 GDC 和 LDC,分別使用 GCC 和 LLVM 後端。DMD 以編譯速度塊而著稱,而 LDC 和 GDC 則以在很短的編譯時間內生成快速生成機器代碼而著稱。你可以自由選擇其中一個以適應你的使用情況。
預設情況下,D 語言是採用垃圾收集[22]的記憶體分配方式的。你也可以選擇手動進行記憶體管理,如果你想的話,甚至可以進行引用計數。一切選擇都是你的。
更多在這個簡要的討論中,還有許多 D 語言好的特性沒有涉及到。我強烈推薦閱讀 D 語言的特性概述[23],這是隱藏在標準庫[24]中的寶藏,以及 D 語言的使用區域[25],從而進一步瞭解人們用它來幹什麼。許多組織已經使用 D 語言來進行開發[26]。最後,如果你打算開始學習 D 語言,那麼請看這本書 D 語言程式設計[27]。
(題圖:opensource.com)
via: https://opensource.com/article/17/5/d-open-source-software-development
作者:Lawrence Aberba[28] 譯者:ucasFL 校對:wxy
本文由 LCTT 原創編譯,Linux中國 榮譽推出
[1]: D 程式設計語言 - https://dlang.org/
[2]: 程式設計範式 - https://en.wikipedia.org/wiki/Programming_paradigm
[3]: 範本 - http://ddili.org/ders/d.en/templates.html
[4]: 條件編譯 - https://dlang.org/spec/version.html
[5]: range - http://ddili.org/ders/d.en/ranges.html
[6]: 陣列切片 - https://dlang.org/spec/arrays.html#slicing
[7]: 與 C 代碼進行自然地對接 - https://dlang.org/spec/interfaceToC.html
[8]: D 中也是可調用的 - https://dlang.org/spec/cpp_interface.html
[9]: Python - https://code.dlang.org/packages/pyd
[10]: Objective-C - https://dlang.org/spec/objc_interface.html
[11]: Lua - http://beza1e1.tuxen.de/into_luad.html
[12]: Fortran - http://www.active-analytics.com/blog/interface-d-with-c-fortran/
[13]: 語法糖 - https://en.wikipedia.org/wiki/Syntactic_sugar
[14]: ddoc - https://dlang.org/spec/ddoc.html
[15]: Contract - http://ddili.org/ders/d.en/contracts.html
[16]: 範本參數 - http://ddili.org/ders/d.en/templates.html
[17]: 通用函式呼叫語法(UFCS) - http://ddili.org/ders/d.en/ufcs.html
[18]: foreach - http://ddili.org/ders/d.en/foreach.html
[19]: 單元測試 - https://dlang.org/spec/unittest.html
[20]: Dub - http://code.dlang.org/getting_started
[21]: Dub package registry - https://code.dlang.org/
[22]: 垃圾收集 - https://dlang.org/spec/garbage.html
[23]: D 語言的特性概述 - https://dlang.org/comparison.html
[24]: 標準庫 - https://dlang.org/phobos/index.html
[25]: D 語言的使用區域 - https://dlang.org/areas-of-d-usage.html
[26]: 使用 D 語言來進行開發 - https://dlang.org/orgs-using-d.html
[27]: D 語言程式設計 - http://ddili.org/ders/d.en/index.html
[28]: Lawrence Aberba - https://opensource.com/users/aberba