Module 如何使用Fortran 90模块数据

Module 如何使用Fortran 90模块数据,module,fortran,conventions,fortran90,Module,Fortran,Conventions,Fortran90,假设您有一个Fortran 90模块,其中包含许多变量、函数和子例程。在您的使用语句中,您遵循哪种约定: 显式声明您在中使用的变量/函数/子例程,仅:语法,例如使用[module_name],仅:variable1,variable2,… 插入毛毯使用[模块名称] 一方面,only子句使代码更加冗长。然而,它迫使您在代码中重复自己,如果您的模块包含大量变量/函数/子例程,那么事情开始变得难以控制 下面是一个例子: module constants implicit none real,

假设您有一个Fortran 90模块,其中包含许多变量、函数和子例程。在您的
使用
语句中,您遵循哪种约定:

  • 显式声明您在
    中使用的变量/函数/子例程,仅:
    语法,例如
    使用[module_name],仅:variable1,variable2,…
  • 插入毛毯
    使用[模块名称]
  • 一方面,
    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的
    使用modulename
    与来自modulename import*
    的Python的
    进行比较。在以下情况之前一直处于堆栈溢出状态的主题:

      • ,马克·罗迪提到: 不要使用“从模块导入*”。对于 任何合理的大型代码集,如果 您的“导入*”很可能是 将其固定到模块中,无法 被移除。这是因为它是 难以确定使用了哪些项目 在代码中,来自“模块”, 向东直奔主题 如果你认为你不使用 进口不再,但它的极端 很难确定

      • 包含 不要从x导入*-它使 你的代码很难理解,就像 您不容易看到方法的位置 来自(来自x进口*;来自y import*;my_func()-my_func在哪里 定义?)

    因此,我倾向于明确说明我在模块中使用的所有项目

    USE modulename, only : var1, var2, ...
    
    作为

    [如果]您有一个如此大的模块 只觉得有必要添加,这意味着 你的模块太大了。分开


    仅对我而言,使用的主要优点是它避免了用我不需要的东西污染我的全局名称空间。

    这是一个平衡问题

    如果您只使用了模块中的一些内容,那么如果您只添加,以明确指定您正在使用的内容,这是有意义的

    如果您使用了模块中的大量内容,那么只指定后面会有大量内容,因此这就没有什么意义了。你基本上是在挑选你所用的东西,但真正的事实是你依赖于这个模块作为一个整体

    然而,最终最好的哲学是这样的:如果您担心名称空间污染,并且您有一个非常大的模块,您觉得必须只添加,这意味着您的模块太大了。分开


    更新:Fortran?只需用python重新编码;)

    我以前只使用modulename
    -然后,随着我的应用程序的发展,我发现越来越难找到函数的源代码(不使用grep)-办公室中的其他一些代码仍然使用每个文件一个子例程,这有它自己的一系列问题,但它使使用文本编辑器浏览代码并快速跟踪所需内容变得更加容易


    在经历了这一切之后,我变成了一个在可能的情况下只使用<代码>使用<代码>的人。我还开始学习Python,并以与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
    排序,而是更多的
    所有的stuffivebeenmeaningtosorout
    种类,那么它当然不会有什么帮助。无论如何,我有幸通过这种方式获得了更容易进入大脑的代码。

    我知道我参加聚会有点晚了,但如果你只需要一组常量,而不需要计算值,你可以像C一样创建一个包含文件:

    在文件中, e、 例如

    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
    

    编辑以删除“real(4)”,因为有些人认为这是一种不好的做法。

    同意前面给出的大多数答案,
    使用…,只有:…
    才是解决方法,在有意义时使用类型,尽可能多地应用。另一个建议是在导入的模块中使用适当的命名约定,以及
    private
    /
    public
    语句

    例如,
    netcdf
    库使用
    nf90
    ,这限制了导入方的名称空间污染

    use netcdf  ! imported names are prefixed with "nf90_"
    
    nf90_open(...)
    nf90_create(...)
    nf90_get_var(...)
    nf90_close(...)
    
    类似地,此库的包装器使用
    nc\u
    nc\u read
    nc\u write
    …)

    重要的是,对于这样的设计,其中
    使用:…,仅:…
    变得不那么相关,您最好通过在标题中设置适当的
    私有
    /
    公共
    属性来控制导入模块的名称空间,以便读者快速查看它就足以评估“污染”的级别他们面临着挑战。这与
    use…(使用…)基本相同,只是:。。。