为何选择 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
, trusted
与 safe
。任何代码默认都为系统级(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 如何?想要深入了解吗?这里有一些好的选择: