D:全球变量不好吗?

时间:2015-12-08 07:42:39

标签: d

有时我需要获取变量,可以从任何代码位置访问。但我经常听到全局变量很糟糕。对于这种情况,D的最佳做法是什么?

现在我的代码看起来像:

string roothtml;
static this()
{
    roothtml = buildPath(getcwd, "html");
}

void main()
{
//
}

这是好的还是坏的做法?

2 个答案:

答案 0 :(得分:2)

由于一些原因,全局变量存在问题。

  • 在您阅读时,更难跟踪变量的来源。这使得使用全局变量更难理解函数。
  • 跟踪变量的使用位置更加困难。这使得修改全局变量的使用方式变得更加困难。
  • 注入测试数据和测试存根更加尴尬。
  • 测试状态将溢出到其他测试。
  • __gshared全局变量需要锁定或不变性。
  • 线程局部全局变量是线程本地的,因此您无法将写入传播到所有线程。
  • 任何全局变量都要求您考虑是否需要线程本地或__gshared
  • 如果您需要将单租户应用程序转换为多租户应用程序,那么如果您使用全局变量将会很痛苦。它比您可能怀疑的更常见。
  • 在运行应用程序时,必须注意不要使用-unittest进行构建,这样就不会在静态构造函数中删除初始化的全局状态。

从好的方面来说,您不必在任何地方传递全局状态。您不必经常使用方法对象重构方法。您不必引入依赖注入系统。当它没有咬你时非常方便。

答案 1 :(得分:1)

这取决于你对“全球”的真正含义。在上面的例子中,我会说它很好。 您似乎正在显示main模块,该模块可能不应导入 任何事情。换句话说,它不是真正的全局,它是主要的本地 模块。

真的没那么不同
class Main {
  private string _roothtml;
  static this() { _roothtml = buildPath(getcwd, "html"); }
  void run() { }
}

即使不是你的main,也不是 module系统为其提供保护 拥有。只需在private上粘贴roothtml即可将其封装在模块中 (无论如何,在主模块中执行此操作并不会有什么坏处,只是为了清楚)。

这样的模式广泛应用于git的源代码中。而不是 你有一个主模块调用给定命令的函数 有许多main函数 - 每个顶级命令一个。

例如,看看 upload-pack.c

查看在源文件顶部声明的那些变量? 如果代码被包含在一个类中,代码是否会更清晰或更安全 典型的OOP风格或者更纯粹地传递给每个函数 功能风格?

每个源文件都充当给定命令的封装单位。这种风格并不总是合适的,但对于一个可以被认为是一组不同命令的程序,它可以比替代方案更清晰。

最终,答案将特定于上下文,您的给定项目,以及 你的个人风格。一般来说,跨模块全局变量是必须的 怀疑地看待,但模块级变量有时可以更清晰 而不是替代品。