module - 将模块变量设为私有
问题描述
在过去的几年里,我一直在创建几个带有子例程的模块,然后将它们用于不同的项目。当我在与这些模块中定义的变量名称冲突的项目特定文件之一中定义参数变量时,我遇到了问题。是否可以将这些名称设为子程序私有或模块私有?
这是一个例子。假设我有以下模块:
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
在主程序中定义为与x
子程序不同维度的参数,test1
编译时会出现问题(违反形状匹配规则)。有没有办法x
在模块内使模块mymod
私有?
我知道一个选项可能是在我的模块中使用“非常见”变量名称或有一个禁止名称列表,但这在这一点上似乎很复杂(需要编辑太多文件并且失去与这些书籍/论文的符号一致性概述了程序),并且会使与同事的协作更加困难。
解决方案
两个不同的问题合二为一:
为什么示例程序无法编译:
这与公共或私有无关,或x
在程序本身中定义。
x
这与在模块中作为参数定义为一维数组而在主程序中y
是标量这一事实有关。
试试看,去掉x
主程序中的声明,还是会失败。
(事实上,声明无论如何都不会那样工作,您声明x
为二维数组(形状 2, 1),然后给它一个一维数组。您必须执行以下操作:
real, dimension(2, 1), parameter x = reshape([1.0, 2.0], [2, 1])
但是要摆脱您描述的错误,您要么需要通过删除(:)
后面的来更改子例程接口real, intent(in) :: x
,要么将调用更改为call test1([y])
.
当 2 个模块导入不同的同名变量时,你可以做什么:
如果你说有这个会有所不同:
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
私有:implicit none real, parameter, private :: x = 2.0
或者
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 ...
重命名其中一个或两个
x
:use modA use modB, only: xB => x ... call subA(xB(1))
推荐阅读
- javascript - XMLHTTPRequest inside forEach loop doesn't work
- c - 释放“struct”中用作“%union”模型的指针
- php - PHP Google API:如何获得更清晰的调试信息?
- multithreading - .NET Core 中的数据存储并行化
- scala - 有没有办法通过检查 Scala 中的 Array 元素来过滤 List 的元素?
- ssl - 带有证书身份验证的客户端凭据流 - 安全使用客户端上存储的证书的最佳方法是什么?
- python - Python Flask WTForms 自定义验证器不起作用
- sql - 为 BigQuery 中的值的分位数创建列
- apache-spark - 比较 spark 和 alteryx 的性能
- python - 从 pandas groupby 获得独特的价值记录