2016-02-27 83 views
2

好像有没有简单的方法来防止D的import语句从混浊的全局命名空间:只要你import std.stdio我可以避免使用D导入来污染公共名称空间吗?

module x;  
import std.stdio; 

void main() { 
    writeln("Hello!"); 
} 

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,我可以理解命名空间的缺乏(但我仍然可以用结构和点符号来实现它们)。有没有办法让导入的名称不是如此全球?

回答

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 
} 
+2

只记得'静态导入'是一件事情。这可能是你正在寻找的东西。 – rcorre

+0

你的意思是 - 你刚刚阅读我的评论。 ;) – DejanLekic

+0

哎呀,没有意识到你在我编辑的时候回答了。你的答案可能更好,因为它削减了追逐的权利:) – rcorre

4

您是否在寻找选择性进口(可在http://dlang.org/spec/module.html找到)?

import std.stdio : writeln; 
+0

这很有趣,但'writeln'仍然是全局声明,并不强迫我使用'std.stdio.writeln' – cat

+0

这是什么目的,反正呢?看来我仍然可以在'std.stdio.write'处理,即使我只输入了std.stdio:writeln;' – cat

+1

@cat这是一个当选择性地导入writeln时可以访问std.stdio.write的bug。 AFAIK,选择性进口从未正常工作(https://issues.dlang.org/show_bug.cgi?id=314)。但是,它在发布时应该在2.071中修复,因为已经有许多与导入相关的修补程序已经成为主程序,特别是针对该错误。 –

4

你的例子的问题是你正在调用writeln,而不是它的指针。尝试&writeln。您还应该声明它为static,因此您不必实例化名称空间。 (D中只有静态函数的类与命名空间非常相似)。但是你应该避免人为地创建名称空间,因为D处理冲突的效果非常好,并且只会增加所需的输入。

至于D的导入系统:导入模块中的每个名称都在当前的模块中可用。但是,只要您导入名称冲突的模块,您将不得不使用全名。

+0

“*致电writeln *”我不需要括号来做到这一点? – cat

+0

'别名'的工作方式,我期待无差别。 – cat

+2

@cat [括号是可选的](http://dlang.org/spec/function.html#optional-parenthesis) – sigod

5

这是相当简单 - 如果你不喜欢的命名空间污染,那么你必须做静态导入

这里是d规范说什么(http://dlang.org/spec/module.html,部分“静态导入”):

基本进口相对较少的模块和进口程序工作。如果有大量导入,名称冲突可能会在各种导入模块中的名称之间开始发生。阻止这种情况的一种方法是使用静态导入。静态导入需要一个使用完全合格的名称来引用模块的名称:

例子:

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;

相关问题