什么时候可以使用Global变量


22

好的,所以这确实是一个恶魔拥护者的问题。

什么时候可以使用全局变量,如果永远不能,那么您将使用什么替代方法?

这个问题的一个有趣的例子是,公共静态类字段与全局字段有何不同?


5
代码完整,第二版,第13.3节。
杰里·科芬

1
多线程应用程序几乎需要全局变量。
AQUA

请参阅软件耦合
PP。

4
@aqua多线程应用程序是全局变量最具破坏性的地方。每个人都讨厌复杂的锁定逻辑。
luiscubal

1
@JerryCoffin如果张贴链接作为答案而不引用相关段落是不正确的做法,那么引用书的一部分而不引用相关段落也是如此。尤其是这样,因为书无法像网页那样自由和容易地获得。
Braden Best

Answers:


18

据我所知,公共静态字段基本上是全局的,因为它可以从任何地方调用,但它不会阻塞名称空间。

我个人唯一在代码中使用“全局”变量的形式是不可更改的公共静态字段。在这种情况下,不必担心该值会被程序的其他部分弄乱,当然,它比每个类中具有十二个具有相同永久值的变量好得多。


2
我将不可变字段称为常量
aioobe

14

就个人而言,我使用全局变量进行运行时配置-如果配置属性是在应用程序启动时加载的,并且仅很少更改(并且仅在一个位置更改),将其传递给可能需要使用的每种方法是很糟糕且容易出错的在某个时候。最好使用可以从任何需要使用的地方引入范围的东西,因为这样不会使您的方法签名和调用站点变得混乱不清。


您将为此使用纯全局变量还是公共static / Singleton?
ocodo

1
@Slomojo:绝对不是单身。根据情况,可以是配置类上的静态变量,也可以是带有CONFIG_CFG_前缀的纯全局变量。
Anon。

+1我建议的一个更改是说“ ...容易将其传递给每个其他类中的所有其他方法”。否则,可以使用任何有用的方法来分类-我认为是单例。
Michael Durrant

8

实际上,不包括实时/嵌入式系统,只应将全局变量用于常量值。如果您觉得没有他们就无法解决问题,则可能是您做错了什么。

另外,查看Singleton模式,当您需要某些东西来拥有全局访问点时,它可以为全局变量提供更好的解决方案。


8
我可能会建议避免使用Singletons。
ocodo

我并不是说单身人士很棒,但我仍然认为它们比全局变量要好得多。
达沃·扎德拉(DavorŽdralo)

常数值仅需要在与其相关的区域/模块中可访问。常数TIMES_TO_ITERATE_THROUGH_THIS_PARTICULAR_LOOP仅在出现“此特定循环”的一个文件/类/部分中相关。
克苏鲁

1
单身人士的字段全局变量,因此我看不出有什么区别。
sleske

1
@Cthulhu让我引述自己:“在那种情况下,当您需要某些东西来拥有全局访问点时”。
2013年

6

全局变量的问题在于,您需要在代码的任何地方都意识到它们。但是,一旦您决定需要了解特定的全局变量,那么大量使用它就不会有更多的损失。因此,我的观点是,您应该只有很少的全局变量,但是只有很少的全局变量,您应该获得最大的里程数。

对于另一个我有这种感觉的示例,请看一下在Ruby中使用mixins。


对于这些全局变量的用法,您会建议使用哪种示例用例?
ocodo

1
@Slomojo:我不介意的全局变量示例是在Perl中使用@ARGV和$ _。我介意的一个示例是使用全局变量将廉价参数传递给子例程。
btilly

5

这全都与名称空间有关。

想象一下,世界上每个人都有相同的姓氏。真是一团糟。

(在印度,锡克教徒的姓氏全都相同:Singh-看一眼)


6
使用的是所有关于命名空间,但现在它是关于线程安全。
dan04 2011年

6
@ dan04这是关于在远处不具有令人毛骨悚然的动作的丑陋设计。
汤姆·霍顿

2
@汤姆:也许我们可以这样称呼,“量子编程”
Christopher Mahan

4

简短版本:在简化程序推理时。通常情况是广泛使用的某种类型的全局状态或静态资源。

加长版:汤姆·霍顿(Tom Hawtin)说:“远距离执行怪异的动作” ...这正是全局变量的问题-您必须知道它的使用位置以及使用方式,否则您可能会发现一些非常奇怪且难以追踪的东西错误。本地人只不过是一种减少程序员为了推理程序而需要理解的范围的策略。

知道使用它们的地方的另一个问题是,您可能会得到重复的全局变量-在这种情况下,由于大多数程序获取并设置了var1,而在几个地方使用了var2时,事情可能会变得很奇怪相同的信息。特别是当多个人正在使用同一代码时。IDE有助于发现使用方法,从而降低了全局变量的成本,但对于重复项却无济于事。

您拥有的全球化者越多,跟踪他们发生的事情就越困难。它们应该很少而且相差很远。


最终,拥有可变的全局变量不是一个好主意。唯一体面的例外是在占用极其紧凑的硬件资源(例如嵌入式编程)的情况下工作。至少,应将常规编程中的全局变量候选者分解为类或模块的静态成员,任何易变的事物也应被视为特殊情况,在多线程环境中工作时更是如此。使用锁定/期货/承诺或线程/交易安全性的其他方法。-既然没有人提到它,就看到了餐饮哲学家的问题。
ocodo

1
毫无疑问,线程会使可变全局变量变得更难使用,但是由于事件,您可能会遇到相同的基本问题。我同意将下摆作为静态成员的建议,并且会进一步说,理想情况下,它们应该是PRIVATE静态成员。
jmoreno

3

具有全局性和单例性的两个陷阱是可测试性和可部署性。

对于测试,我已经看到太多过于复杂的测试工具,仅用于处理计划不周的全局寿命和单例寿命。确保任何此类对象都具有明确且简单的启动和拆卸规则。

至于可部署性,有两种情况需要考虑。首先,您的全局对象将如何生活?它在静态或动态库中吗?如果该全局对象重新用于插件,您会获得额外的副本吗?其次,当将该全局对象放入并行应用程序时会发生什么?它是线程安全的吗?

总体而言,我认为这些原因意味着全局和单例仅在例外情况下使用。


2

关键嵌入式系统的开发通常涉及全局变量的使用。

堆栈大小很小,所有内容都是静态分配的(malloc()禁止使用),全局变量从它们所属的库外部隐藏。


0

在一个可怕的VB6代码库中,滥用全球语言就像没有明天一样,我犯了一个新的错误:

Global CsExt As New TheAppBeingRewrittenInCSharpWhileVb6CodeIsStillBeingMaintained

我认为这是全局对象的少数有效用例之一。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.