【发布时间】:2017-09-12 13:32:51
【问题描述】:
我对模型/变量使用的最佳实践有疑问:
假设我有一个包含一些变量/参数定义的模块和一些使用这些变量的子例程。
我不需要在子例程中显式使用这些变量,因为它们是从父模块继承的 - 但这样做会更好吗?
例子:
module test
implicit none
integer, parameter :: a = 1
real :: x
contains
subroutine idk(y,z)
real, intent(in) :: y
real, intent(out) :: z
if(a .eq. 1) then
z = x*y + 5.
else
z = x*y - 5.
end if
end subroutine idk
end module test
上面的例子应该可以正常工作,但添加会更好
use test, only: a,x
到子程序idk的声明部分?
在我的推理中,这里有两个要点:
1) Pro:显式添加这一行让我很容易看到子程序中实际需要哪些变量。 在许多情况下,模块包含相当多的变量,但每个子例程中只需要几个变量。因此,为了更好地理解,添加这一行将是有益的。
但是
2) 相反:在相当多的情况下,需要很多上面声明的变量/参数(有时编号超过 100 个参数)。在子例程的开头显式使用这些只会不必要地使代码混乱,降低代码的可读性。
如果只需要包含几个变量,第 1 点最重要,而第 2 点只有在需要包含许多变量时才重要。但我认为为少数变量做一件事而为许多变量做另一件事是愚蠢的 - 一旦你选择了一个约定,你应该坚持它恕我直言......
有没有这方面的最佳做法?
补充: 或者,可以将子例程声明为
subroutine idk(b,w,y,z)
然后将其称为idk(a,x,y,z)。
一方面,如果我以后决定要将idk 与其他变量一起使用,这会给我更大的灵活性。
另一方面,如果我稍后更改某些内容,也会增加出错的风险(例如,我意识到我不需要参数a 作为条件,而是参数c。在第一种情况下,我只是简单地在子程序中切换出a -> c。但在最后一种情况下,我需要将每个调用更改为idk(c,...)。如果这些调用很多,这很容易出错)
非常感谢您的意见!谢谢!
【问题讨论】:
-
另一种选择是将参数放在单独的模块中。
-
我总是谨慎处理主机关联,并在源代码中记录它。请注意,即使您决定将必要的变量作为 args 传递给内部过程,主机变量仍可能被“意外”访问/修改。我认为这比忘记将变量传递给外部子程序更糟糕,因为在这种情况下,您会立即看到错误。
-
我考虑将参数放在单独的模块中。我遇到的问题是:代码很大,我有很多参数。通过将变量声明与使用它们的主要例程放在一起,它似乎组织得很好。外包它们基本上会使模块的数量增加一倍(除非我把它们都放在一个大的控制文件中,这可能会相当混乱,因为它确实很大),使得找到我需要的东西变得更加困难。但现在我很担心这会给我带来麻烦。如何确保不会无意中修改主机关联变量?