Module 使模块变量私有化
在过去的几年中,我一直在创建几个带有子程序的模块,然后将这些子程序用于不同的项目。当我在其中一个特定于项目的文件中定义参数变量时遇到问题,这些文件与那些模块中定义的变量名冲突。是否可以将这些名称设置为子程序专用或模块专用 这里有一个例子。假设我有以下模块:Module 使模块变量私有化,module,fortran,Module,Fortran,在过去的几年中,我一直在创建几个带有子程序的模块,然后将这些子程序用于不同的项目。当我在其中一个特定于项目的文件中定义参数变量时遇到问题,这些文件与那些模块中定义的变量名冲突。是否可以将这些名称设置为子程序专用或模块专用 这里有一个例子。假设我有以下模块: module mymod implicit none contains subroutine test1(x) real, intent(in) :: x(:) print *, x**2.0
module mymod
implicit none
contains
subroutine test1(x)
real, intent(in) :: x(:)
print *, x**2.0
end subroutine test1
end module mymod
然后主程序调用此模块
program main
use mymod
implicit none
real :: y
real,dimension(2,1),parameter :: x = [1.0,2.0]
y = 3.0
call test1(y)
end program main
在这种情况下,如果主程序中的x被定义为与子例程test1中的x具有不同维度的参数,那么编译形状匹配规则时就会出现问题。有没有办法在模块内将模块mymod中的x设置为私有的
我知道可以选择在我的模块中使用非通用变量名,或者有一个禁止使用的名称列表,但在这一点上似乎很复杂,需要编辑太多的文件,并与概述这些过程的书籍/论文失去一致的符号,而且会使与同事的合作更加困难。一个问题中有两个不同的问题: 为什么示例程序无法编译: 这与public或private无关,也与程序本身中定义的x无关 它与以下事实有关:在模块中,作为参数的x被定义为一维数组,而在主程序中,y是标量 尝试一下,删除主程序中的x声明,它仍然会失败 事实上,声明并不是这样工作的,您将x声明为二维数组形状2,1,然后给它一个一维数组。您必须执行以下操作:
real, dimension(2, 1), parameter x = reshape([1.0, 2.0], [2, 1])
但是为了消除您描述的错误,您需要通过删除real后面的:intentin::x来更改子例程接口,或者将调用更改为调用test1[y]
当两个模块导入相同名称的不同变量时,您可以做什么:
如果你这样说,那就不一样了:
module modA
implicit none
real, parameter :: x = 2.0
contains
subroutine subA(k)
real, intent(in) :: k
print *, k*x
end subroutine subA
end module modA
module modB
implicit none
real :: x(3)
end module modB
program progtest
use modA
use modB
implicit none
call subA(x(1))
end program progtest
在本例中,它将尝试从两个模块导入变量x
避免的方法:
将一个x设为私有:
或
或
仅导入所需的零件:
program progtest
use modA, only: subA
use modB
implicit none
...
重命名一个或两个x:
关键是将模块中的所有内容都设置为私有,并且只公开模块中需要公开的实体。在发布的示例OP中,问题绝对不是私有/公共问题。根据示例,他的问题是参数类型不匹配。在隐式NONE之后向模块添加PRIVATE。在PRIVATE语句之后,添加publictest1。这将只公开模块中的test1实体。
real, parameter :: x = 2.0
private :: x
implicit none
private
real, parameter :: x = 2.0
public :: subA
program progtest
use modA, only: subA
use modB
implicit none
...
use modA
use modB, only: xB => x
...
call subA(xB(1))