Fortran 90 最麻烦的问题之一是缺乏命名空间。在上一个问题中“如何使用 Fortran 90 模块数据”来自 Pete,已经讨论了 USE 在 Python 中表现得像“from module import *”的主要问题:模块中声明为 public 的所有内容都会在导入模块的范围内按原样导入。没有前缀。这使得在阅读一些代码时非常非常难以理解给定的标识符来自哪里,以及给定的模块是否仍在使用。
我在上面链接的问题中讨论的一个可能的解决方案是使用 ONLY 关键字来限制导入的标识符和文档它们的来源,尽管当模块非常大时,这非常非常乏味。保持模块较小并始终使用 USE : ONLY 是解决 Fortran 9X 中缺乏命名空间和限定前缀的潜在良好策略。
是否还有其他(不一定更好)的解决策略? Fortran 2k3 标准是否提到了有关命名空间支持的内容?
One of the most troublesome issues with Fortran 90 is the lack of namespacing. In this previous question "How do you use Fortran 90 module data" from Pete, it has been discussed the main issue of USE behaving like a "from module import *" in Python: everything that is declared public in the module is imported as-is within the scope of the importing module. No prefixing. This makes very, very hard to understand, while reading some code, where a given identifier comes from, and if a given module is still used or not.
A possible solution, discussed in the question I linked above, is to use the ONLY keyword to both limit the imported identifiers and document where they come from, although this is very, very tedious when the module is very large. Keeping the module small, and always using USE : ONLY is a potentially good strategy to work around the lack of namespacing and qualifying prefixes in Fortran 9X.
Are there other (not necessarily better) workaround strategies? Does the Fortran 2k3 standard say anything regarding namespacing support?
发布评论
评论(4)
对我来说,这是与模块相关的最令人恼火的 Fortran 功能。唯一的解决方案是为过程、变量、常量等添加公共前缀,以避免命名空间冲突。
可以在模块内部为所有实体(所有公共实体似乎更合适)添加前缀:
缺点是增加了模块内部的代码冗长。作为替代方案,可以使用命名空间前缀包装器模块,例如此处建议的那样。
最后一个是对 Stefano 建议的一个小修改。
即使我们接受冗长的情况,Fortran 语言不区分大小写的事实也迫使我们在实体名称中使用相同的分隔符 (_)。除非我们不使用严格的命名规则,否则很难区分模块名称(作为前缀)和实体名称,例如,模块名称只有一个单词。
For me this is the most irritating Fortran feature related to modules. The only solution is to add common prefix to procedures, variables, constants, etc. to avoid namespace collisions.
One can prefix all entities (all public entities seems to be more appropriate) right inside the module:
Drawback is increased code verbosity inside the module. As an alternative one can use namespace-prefix wrapper module as suggested here, for example.
The last is a small modification of what you, Stefano, suggested.
Even if we accept the situation with verbosity the fact that Fortran is not case-sensitive language force us to use the same separator (_) in entities names. And it will be really difficult to distinguish module name (as a prefix) from entity name until we do not use strong naming discipline, for example, module names are one word only.
凭借多年的 Fortran 编程经验(我一年前才接触 Python),我有一段时间不知道命名空间这样的概念。所以我想我学会了跟踪导入的所有内容,正如高性能马克所说,只使用你有时间做的尽可能多的东西(乏味)。
我能想到的模拟命名空间的另一种方法是将模块中的所有内容声明为派生类型组件。 Fortran 不允许您以与命名空间相同的方式命名模块,但在模块名称中添加 module_ 前缀可能足够直观:
Having several years of Fortran-only programming experience (I got into Python only a year ago), I was not aware of such concept as namespaces for a while. So I guess I learned to just keep track of everything imported, and as High Performance Mark said, use ONLY as much as you have time to do it (tedious).
Another way I can think of to emulate a namespace would be to declare everything within a module as a derived type component. Fortran won't let you name the module the same way as the namespace, but prefixing module_ to module name could be intuitive enough:
Fortran 2003 具有新的
ASSOCIATE
构造,并且不要忘记重命名USE
关联实体的可能性。但我不认为这两者比 Fortran 90 已经提供的更好的命名空间模拟更接近,只是(稍微)更好的解决方法。就像您链接到的问题的一些受访者一样,我倾向于认为具有很多标识符的模块可能应该分成更小的模块(或者,等待 Fortran 2008 并使用子模块),这些天我几乎总是指定一个
USE
语句的 >ONLY 子句(带重命名)。我不能说我很怀念命名空间,但我从来没有真正拥有过它们。
Fortran 2003 has the new
ASSOCIATE
construct and don't forget the possibility of renamingUSE
- associated entities. But I don't think that either of these is much closer to providing a good emulation of namespaces than Fortran 90 already has, just (slightly) better workarounds.Like some of the respondents to the question you link to, I tend to think that modules with very many identifiers should probably be split into smaller modules (or, wait for Fortran 2008 and use submodules) and these days I almost always specify an
ONLY
clause (with renames) forUSE
statements.I can't say that I miss namespaces much, but then I've never had them really.
没有其他人将这一建议作为答案(尽管有人在一个答案的评论中这样做)。因此,我将提交此内容,希望对其他人有所帮助。
您可以通过以下方式模拟名称空间,我希望编译器这样做不会对性能造成明显影响(如果是这样,所有面向对象的 Fortran 编程都会受到影响)。我在我的生产代码中使用了这种模式。对我来说唯一真正的缺点是缺少包含参数变量的派生类型,但我在下面也提供了一个选项。
就我个人而言
,我更喜欢使用
$
而不是_
作为模块变量,但并非所有编译器都喜欢没有编译器标志的编译器。希望这对将来的人有帮助。No one else summited this suggestion as an answer (though someone did in the comments of one answer). So I'm going to submit this in hopes it may help someone else.
You can emulate namespaces in the following way, and I would hope there would be no noticeable performance hit for doing so from the compiler (if so all object oriented Fortran programming is sufferings). I use this pattern in my production code. The only real downfall to me is the lack of derived type contained parameter variables, but I offer an option for that as well below.
And the usage
Personally I prefer using
$
over the_
for module variables, but not all compilers like that without compiler flags. Hopefully this helps someone in the future.