你怎么使用Fortran90模块中的数据
-
11-09-2019 - |
题
让我们说你有一个Fortran90模块包含 很多 变量、职能和子程序。在你 USE
声明,《公约》做你下:
- 明确声明其中的变量/职能/子你用的
, only :
语法,例如USE [module_name], only : variable1, variable2, ...
? - 插入一条毯子
USE [module_name]
?
在这一方面, only
条款使得代码一点的更多详细。然而,它迫使你重复自己的代码如果你的模块包含 很多 变量/职能/子程序,事情开始变得不守规矩的。
这里有一个例子:
module constants
implicit none
real, parameter :: PI=3.14
real, parameter :: E=2.71828183
integer, parameter :: answer=42
real, parameter :: earthRadiusMeters=6.38e6
end module constants
program test
! Option #1: blanket "use constants"
! use constants
! Option #2: Specify EACH variable you wish to use.
use constants, only : PI,E,answer,earthRadiusMeters
implicit none
write(6,*) "Hello world. Here are some constants:"
write(6,*) PI, &
E, &
answer, &
earthRadiusInMeters
end program test
更新 希望有人说喜欢的东西 "Fortran?只是重新编码它在C#!" 所以我可以下投票。
更新
我喜欢 蒂姆*特科姆的答案, ,其中比较Fortran的 USE modulename
与蟒蛇的 from modulename import *
.这一议题已在栈溢出之前:
-
- 在答案, Mark罗迪提及:
不要用'模块进口*'.对于 任何合理的大量代码,如果 你进口*你可能会 巩固它变成的模块,无法 被删除。这是因为它是 难以确定哪些项目使用 在代码是来自'模块', 做这东去点 在那里你觉得你没用 进口了,但其非常 难以确定。
- 在答案, Mark罗迪提及:
-
- 比答案 包含
不这样做,从x进口*-它使 你的代码非常难以理解的,因为 你不能轻易看到的方法 来自(x进口*;从y 进口*;my_func()-在哪里是my_func 定义?)
- 比答案 包含
因此,我倾向于协商一致的方式明确指出的所有项目,我使用一个模块通过
USE modulename, only : var1, var2, ...
和为 斯特凡诺*博里尼定提到,
[如果]你有一个模块这么大的是你 感到不得不只增加,这意味着 你的模块是太大。分裂。
解决方案
这是一个问题平衡。
如果仅使用一些东西从的模块,这是有道理如果你仅加,以明确指定所使用。
如果你使用了很多的东西从模块,仅指定随后将由一个很大的东西,所以它使较小的意义。你基本上是摘樱桃你用什么,但真正的事实是,你都依赖该模块作为一个整体。
然而,在结束最好的理念是这个:如果你关心的名字空间的污染,并且你有一个模块这么大,你觉得不得不只增加,这意味着你的模块是太大。分裂。
更新:Fortran?只是重新编码它在python)
其他提示
我以前只是做 use modulename
-然后,我的应用程序的增长,我发现越来越难以找到源的职能(不转向查询)-其他一些代码浮周围的办事处仍在使用一个子程序,每文件,它有自己的问题,但它使得更容易使用的一个文本编辑器移动通过代码和快速跟踪你需要什么。
后遇到这一点,我已经成为一个转换到使用 use
...only
只要有可能。我也开始拿起蟒蛇,并认为这是相同的方式 from modulename import *
.有很多伟大的事情那个模块给你,但我更喜欢把我的名字空间的全球紧紧地控制。
不完全回答的问题在这里,只是扔在另一个解决方案,我们发现有用的,在一些情况下,如果由于某种原因你不想要分割你的模块,并开始获得名字空间的冲突。你可以用来类型储存的几个名字空间中的一个模块。
如果有一些逻辑组的变量,您可以创建自己的衍生的类型为每个小组,储存的实例,这种类型的模块,然后你可以进口只的组发生的需要。
小例子:我们有很多的数据,其中一些是用户输入和一些结果的杂项初始化。
module basicdata
implicit none
! First the data types...
type input_data
integer :: a, b
end type input_data
type init_data
integer :: b, c
end type init_data
! ... then declare the data
type(input_data) :: input
type(init_data) :: init
end module basicdata
现在如果一个子程序只能使用的数据来自 init
, 你进口:
subroutine doesstuff
use basicdata, only : init
...
q = init%b
end subroutine doesstuff
这绝对不是一个普遍适用的解决方案,则获得一些额外的详细程度,从源类型的语法,那么它当然将几乎没有帮助,如果你的模块是不是 basicdata
排序上,而是更多的一个 allthestuffivebeenmeaningtosortout
种类繁多。无论如何,我有一点运气在得到代码,适合更容易进入大脑这种方式。
主要优势的利用,只有我的是,它避免了污染我的名字空间的全球用的东西我不需要。
同意大多数答复先前给予, use ..., only: ...
是的路要走,使用的类型时,它是有道理的,申请 蟒蛇的思想 尽可能多的。另一项建议是使用适当的命名约定在进口的模块,随着 private
/ public
发言。
例如,《 netcdf
库使用 nf90_<some name>
, ,这限制空间的污染在进口方面。
use netcdf ! imported names are prefixed with "nf90_"
nf90_open(...)
nf90_create(...)
nf90_get_var(...)
nf90_close(...)
同样地, ncio 包装,以此库使用 nc_<some name>
(nc_read
, nc_write
...).
重要的是,这样的设计 use: ..., only: ...
是不太相关的,你会更好地控制空间的进口模块通过设置适当 private
/ public
属性的头,使得我们来看看它将足以满足读者对评估其水平的"污染",他们面临着。这基本上是相同的 use ..., only: ...
, ,但是对进口的模块,因此可以写的只是一次,在每个进口).
有一件事:尽对象的取向和蟒蛇是有关的,一个区别在我的观点是,fortran不真的鼓励的类型限的程序,部分原因在于它是一个相对较新的标准(例如不兼容的一些工具,并不合理,它仅仅是不寻常的),因为它打破了方便的行为,如过程无源型复制(type(mytype) :: t1, t2
和 t2 = t1
).这意味着通常需要进口的类型和所有想要的类型限的程序,而不只是课。仅此一点就使fortran代码的更详细的比较python和实际的解决方案,如前缀的命名《公约》可能派上用场。
海事组织的底线是:选择你的编码式的人将读它(这包括你的后来自),作为教蟒蛇。最好的是更详细 use ..., only: ...
在每次进口,但在某些情况下,一个简单的命名约定将做它(如果你是纪律不够...).
是的,请用 use module, only: ...
.对于大型代码基地与多个程序员,它使代码更容易执行的每个人(或只是使用 grep
).
请不要使用包括使用较小的模块,用于代替。包括一个文本中插入的源代码,不是检查,通过编译器处于同一水平使用模块,看到: FORTRAN:之间的差异包括和模块. Include
通常就更难对于人类和计算机使用的代码,这意味着它不应使用。前。从mpi-论坛:"使用的收获美国金属粉末冶金联合会.h包括文件是强烈反对并且可以被废弃的未来版本中MPI。" (http://mpi-forum.org/docs/mpi-3.1/mpi31-report/node411.htm).
我知道我迟到了一点点到的缔约方,但是如果你只是后一组常数而不一定是计算出的价值,你能做喜欢的C和创建一个包括文件:
内部文件, 例如,常数。对于
real, parameter :: pi = 3.14
real, parameter :: g = 6.67384e-11
...
program main
use module1, only : func1, subroutine1, func2
implicit none
include 'constants.for'
...
end program main
编辑,以删除"真正(4)"因为有些人认为它是不好的做法。