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++ 中使用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 函数不允许退出创建它们的函数)。
- 内部类
- 预处理器
- 具有非虚拟析构函数的多态类型
- 多态值类型 - 在 D 中,
struct
是没有继承和虚拟函数支持的值类型,而class
是支持继承和虚拟函数的引用类型。 - 多重继承 - D 类仅提供 Java 和 C# 风格的多重接口实现。相反,对于代码重用,D 更倾向于组合、
mixin
和alias this
有关更多详细信息,请参阅 D 编程 书籍。