我可以避免使用D导入污染公共命名空间吗?

时间:2016-02-27 20:29:31

标签: namespaces d

似乎没有简单的方法可以阻止D的import语句蒙上全局命名空间:

module x;    
import std.stdio;

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

只要import std.stdiowriteln现在就是全球性的。来自[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,我可以理解缺少命名空间(但我仍然可以使用结构和点符号来实现它们)。有没有办法让导入的名称不那么全球化?

4 个答案:

答案 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的导入系统:导入模块中的每个名称都可以在当前模块中使用。但是,只要导入名称冲突的模块,您就会被迫使用全名。