文章

为何选择 DLang

为何选择 DLang

碎碎念

当被问起为何选择 DLang,亦或是其他人想知道 DLang 为什么做的比 C++ 更好(虽然它还不够完完全全的取代 C++,它不是一个 C++ 的分支, Coal 才是),是时候总结一篇文章了。

入门

哲学与能力

DLang 的设计哲学便是保持开发。DLang 注重最小最轻的标准库,保证里面只有一切你会用到的东西,而不会有其他无关的东西。DLang 保持关心最核心的问题。

DLang 拥有自己的垃圾标记与垃圾回收器(GC)。通过 @nogc 注解来禁用 GC 的工作,之后需要手动回收。

DLang 允许安全编程,远离肮脏的不安全指针。

DLang 拥有强大的与 C/C++ 的兼任能力,同时拥有自己的开放源代码标准库 STD,初学阶段我们会在顶部导入包 std.stdio。这个包已经导入了你在 C 中会涉及到的库 stdio.h

快速上爪

DLang 拥有相当平滑的入门曲线,因为它适应多种语言开发者。只可惜暂时没有较为知名的 DLang 华语论坛。

我们先看一段例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 让我们看起来像是从 C 语言迁移过来的!
int main() {
	printf("%s","Hello world!");
	return 0;
}

// 让我们以 D 语言的风格编写程序!
void main() {
    writef("%s", "Hello world!");
}


// 让我们看起来是从 Java 迁移过来的!
void main(string[] args) {
    writeln("Hello world!");
}

DLang 的编译器分为三种,官方标配的 DMD, 基于 GCC 的编译器 GDC,亦或是基于 LLVM 的编译器 LDC。

在 Windows 端,我们通常推荐使用 DMD 或 LDC,而 Unix 终端可自便。

其他特性

依照官网描述,DLang 依然有很多强大且会用到的特性。在此我会更直观的描述 DLang 的强大之处:

  • 高等级的抽象建模(泛型,模板与委托);
  • 高性能的快速编译语言;
  • 静态编程语言;
  • 系统级 API 与嵌入式编程;
  • 安全子集(Safe D);
  • 易理解,可维护的代码;
  • 兼容 C 语言的二进制接口(相关文档见官网);
  • 有限兼容 C++ 的二进制接口(相关改动见 D 1.0 迁移至 2.0);
  • 多范式编程(甚至汇编!),且拥有平滑学习曲线;
  • 契约除错与内置的单元测试。

更多你会感兴趣的

我之前提到过 DLang 是我在完成 PineappleScript 这个大饼之前用作系统维护的语言。是的,DLang 甚至适合作为脚本程序!让我们看一看运行指令:

编译:dmd [filename]

执行(不输出编译产物):rdmd [filename]

DLang 的包管理器是 DUB。使用 DUB 执行一定会产生编译产物。

DUB 构建编译:dub build

DUB 构建执行:dub run

对于 Unix,在首行放置 Shebang( #!/bin/sh 等)可以直接作为脚本执行程序。

强大的导入模块

随意导入

你的下一个 import, 何必要写在头部? DLang 允许你在 任何地方 import 一个新的模块,甚至只抽取部分函数进行导入。

1
2
3
4
void main() {
    import std.stdio : writeln; // 在函数内导入的模块的作用域仅限于当前函数。此处单独导入了 writeln 函数作用给 main 函数!
    writeln("Hello world!");
}

公开匹配

在 DLang 中,对 import 进行公开(public import ...) 会让导入当前模块的地方同时能够自动导入被公开的部分。因此 public 时一定要注意当前模块与导入模块的关系是否合适。

但是我们依然有一种常见场景——目录导入。

DLang 中约定,直接导入模块目录可以导入全部内容。而 package.d 可以管理模块是否需要公开(这是可选的,我们通常是这样约定的)。

1
2
3
4
5
6
7
8
// package.d
module app.apps

public:
import app.apps.app1;
import app.apps.app2;
import app.apps.app3;

在直接导入 app.apps 时,将会自动导入其余三个文件。当如,package.d 中也是可以写代码的。当你不关心模块时可以这么做。

安全编程

远古代码总是像是粪坑,人们都知道最下面有金子,但是人们望而却步。因为粪坑的顶部是不安全的分配和对指针的运算,甚至是越界访问。DLang 决定开创一个西方极乐世界,若是开发者的心中有一片净土,那么未来一定能前往极乐世界的。

DLang 中的代码安全等级分为 system, trustedsafe。任何代码默认都为系统级(system)。

来看一段代码:

1
2
3
4
void main() @safe {
    int* a = new int;
    int* b = a + 5; // Error
}

main 函数被标记了 @safe,那么它就是安全的。来看第一段:

int* a = new int; 这一段中我们为 a 分配了一块内存,分配者是 GC。分配后会返回内存托管的指针。当指针不再使用,GC 会立刻出动。再来看第二段:

int* b = a + 5; // Error 我在注释中写了 Error,因为这一段是不成立的。看起来没什么问题?不,安全编程中不可以做这种不干不净的事情。如果你想要内存,那么你得自己去拿,规矩你是知道的。

安全的函数只能调用另一个安全的函数,除非那个函数是 @trusted 的。当有这个标记,那么编译器会默认这段函数的安全性由开发者管理,也就是所谓的 Unsafe 编程。

拓展阅读

觉得 DLang 如何?想要深入了解吗?这里有一些好的选择:

本文章以 CC BY 4.0 授權