Fortran 90最棘手的问题之一是缺少命名空间。在How do you use Fortran 90 module data的上一个问题“Pete”中,已经讨论过USE的主要问题,就像Python中的“from module import *”:模块中声明为public的所有内容都被导入为 - 在导入模块的范围内。没有前缀。这非常非常难以理解,同时阅读一些代码,其中给定的标识符来自,以及是否仍然使用给定的模块。
我在上面链接的问题中讨论的一个可能的解决方案是使用ONLY关键字来限制导入的标识符并记录它们来自哪里,尽管当模块非常大时这非常非常繁琐。保持模块较小,并始终使用USE:ONLY是一个很好的策略,可以解决Fortran 9X中缺少命名空间和限定前缀的问题。
还有其他(不一定更好)的解决方案策略吗? Fortran 2k3标准是否有关于命名空间支持的说法?
答案 0 :(得分:6)
对我而言,这是与模块相关的最令人恼火的Fortran功能。唯一的解决方案是为过程,变量,常量等添加公共前缀,以避免命名空间冲突。
可以在模块内部为所有实体(所有公共实体似乎更合适)添加前缀:
module constants
implicit none
real, parameter :: constants_pi = 3.14
real, parameter :: constants_e = 2.71828183
end module constants
缺点是增加了模块内部的代码详细程度。作为替代方案,可以使用名称空间前缀包装器模块,例如建议here。
module constants_internal
implicit none
real, parameter :: pi = 3.14
real, parameter :: e = 2.71828183
end module constants_internal
module constants
use constants_internal, only: &
constants_pi => pi, &
constants_e => e
end module constants
最后一个是对斯蒂法诺建议的一个小修改。
即使我们接受冗长的情况,Fortran不区分大小写的语言也迫使我们在实体名称中使用相同的分隔符(_)。在我们不使用强命名规则之前,将模块名称(作为前缀)与实体名称区分开来真的很困难,例如,模块名称只是一个单词。
答案 1 :(得分:5)
拥有几年Fortran编程经验(仅在一年前进入Python),我暂时不知道命名空间这样的概念。所以我想我学会了跟踪所有导入的东西,正如高性能马克所说的那样,只需要你有时间去做(繁琐)。
我可以想到的另一种模拟命名空间的方法是将模块中的所有内容声明为派生类型组件。 Fortran不会让你以与命名空间相同的方式命名模块,但是将module_添加到模块名称之前可能足够直观:
MODULE module_constants
IMPLICIT NONE
TYPE constants_namespace
REAL :: pi=3.14159
REAL :: e=2.71828
ENDTYPE
TYPE(constants_namespace) :: constants
ENDMODULE module_constants
PROGRAM namespaces
USE module_constants
IMPLICIT NONE
WRITE(*,*)constants%pi
WRITE(*,*)constants%e
ENDPROGRAM namespaces
答案 2 :(得分:3)
Fortran 2003具有新的ASSOCIATE
构造,不要忘记重命名USE
相关实体的可能性。但我认为这两者中的任何一个都不比Fortran 90已经拥有的名称空间更好,只是(稍微)更好的解决方法。
与您链接到的问题的一些受访者一样,我倾向于认为具有很多标识符的模块可能应该拆分为更小的模块(或者,等待Fortran 2008并使用子模块),这些天我几乎总是指定ONLY
语句的USE
子句(带有重命名)。
我不能说我错过了名称空间,但后来我从来没有真正使用它们。