似乎没有简单的方法可以阻止D的import语句蒙上全局命名空间:
module x;
import std.stdio;
void main() {
writeln("Hello!");
}
只要import std.stdio
,writeln
现在就是全球性的。来自[language with namespaces]
,如果我只能引用std.stdio.writeln
,那将是很好的,特别是在一两周内,我可以很容易地告诉writeln
提供什么。
在阅读Namespaces with classes and structs?之后,在我看来,这应该做我想做的事情(就像它一样笨拙):
module x;
import std.stdio;
class String {
struct write {
auto println = writeln;
}
}
void main() {
String string = new String();
string.write.println("Hello!");
}
但是我得到了Error: variable [...] type void is inferred from initialiser [...], and variables cannot be of type void
,这意味着函数别名已经用完了。
如果我写C,我可以理解缺少命名空间(但我仍然可以使用结构和点符号来实现它们)。有没有办法让导入的名称不那么全球化?
答案 0 :(得分:7)
我倾向于同意@weltensturm - D优雅地处理冲突,并且 人为地创建名称空间只会让事情变得混乱。
D(恕我直言)的一个不错的部分就是避免你在其他地方看到的长名 语言,不用担心会发生可怕的事情。
但是,如果你真的需要,请查看文档 modules,其中显示了如何重命名模块:
import io = std.stdio;
void main()
{
io.writeln("hello!"); // ok, calls std.stdio.writeln
std.stdio.writeln("hello!"); // error, std is undefined
writeln("hello!"); // error, writeln is undefined
}
您还可以使用静态导入,因此您必须使用完全限定名称:
static import std.stdio;
void main()
{
std.stdio.writeln("hello!"); // OK
writeln("hello!"); // error, writeln is undefined
}
答案 1 :(得分:5)
这很简单 - 如果你不喜欢命名空间污染,那么你必须做静态导入。
以下是D规范所说的内容(http://dlang.org/spec/module.html," Static Imports"):
基本导入适用于模块和导入相对较少的程序。如果有大量导入,则可以在各种导入模块中的名称之间开始发生名称冲突。阻止这种情况的一种方法是使用静态导入。静态导入需要使用完全限定名称来引用模块的名称:
示例:
static import std.stdio;
void main() {
writeln("hello!"); // error, writeln is undefined
std.stdio.writeln("hello!"); // ok, writeln is fully qualified
}
如果我的代码只需要模块中的一个或两个符号,我使用Max Alibaev提到的选择性导入。说我会使用writeln()很多。 - 然后我很可能在我的D代码中有一行import std.stdio : writeln;
。
答案 2 :(得分:4)
您是否正在寻找选择性进口(可在http://dlang.org/spec/module.html上找到)?
import std.stdio : writeln;
答案 3 :(得分:4)
你的例子的问题是你正在调用writeln而不是它的指针。试试&writeln
。您还应将其声明为static
,这样您就不必实例化命名空间。 (在D中只有静态函数的类就像命名空间一样)。但是你应该避免人为地创建命名空间,因为D处理冲突非常好,只会增加所需的输入。
对于D的导入系统:导入模块中的每个名称都可以在当前模块中使用。但是,只要导入名称冲突的模块,您就会被迫使用全名。