在 fortran 中命名派生类型的良好做法

Posted

技术标签:

【中文标题】在 fortran 中命名派生类型的良好做法【英文标题】:Good practice in naming derived types in fortran 【发布时间】:2013-04-04 19:53:52 【问题描述】:

我想通过使用 OOP 来优化我在 Fortran 中的代码的可读性。 因此,我使用派生类型。命名类型和派生类型的最佳做法是什么?

例如,是否更好:

type a
    real :: var
end type
type(a) :: mya

或者总是以type_ 开头类型名称,例如type_a?我喜欢这个,但也许可以找到更好的想法。

此外,如果类型有太多“级别”,那么使用可读性较差的短名称还是使用较长的名称会更好(那么为什么)。例如,在a%b%c%d%e 中,如果 a、b、c、d 和 e 的长度与 country%hospital%service%patient%name 中一样长 8 个或更多字母,那么可读性似乎又是一个问题。

非常欢迎专家的建议。

【问题讨论】:

我更喜欢变量的描述性名称。稍后您会忘记短名称的含义。如果在嵌套名称中% 的任一侧使用空格,我认为可读性会提高。我看过这个推荐的。 【参考方案1】:

这对 Fortran 来说没什么特别的。您可以使用其他语言的编码建议。 通常,类型名称不使用任何前缀或后缀指定。在许多语言中,类名以大写字母开头。您也可以在 Fortran 中使用它,即使它不区分大小写。请确保不要将带有小写字母的名称用作变量名。

一个好的编码指南的例子是this,你可以很容易地将它改编为 Fortran。另外,请查看 MRC 或 RXX 等书籍中的一些 Fortran 示例。 OS 也很有用。

如果字母与书面方程式中使用的字母不同,我建议不要使用太短的组件名称。在这种情况下,它可以使用。

使用associate 构造或指针为嵌套名称创建别名,例如country%hospital%service%patient%name

【讨论】:

【参考方案2】:

根据我的经验,由于 Fortran 的命名模块、缺少命名空间和不区分大小写等原因,OO Fortran 中的命名问题比其他语言(例如 C++)更多。不区分大小写会造成伤害,因为如果将类型命名为 Foo,则不能有一个名为 foo 的变量,否则会出现编译器错误(使用 gfortran 4.9 测试)。

我确定的规则是:

每个 Fortran 模块都提供一个名为 Namespace_Foo 的主类。 Namespace_Foo 类可以作为Namespace/Foo_M.f90 在您的源代码树中定位。 类变量是具有描述性、小写名称的名词,例如 barbar_baz。 类方法是具有描述性(但尽可能简短)名称的动词,并使用重命名 search => Namespace_Foo_search。 如果没有简单的替代方法,可以将 Namespace_Foo 类的实例命名为 foo(没有命名空间)。

这些规则使得在 Fortran 中镜像 C/C++ 类 Namespace::Foo 或将 C++ 类绑定(使用 BIND(C))到 Fortran 变得特别容易。它们还避免了我遇到的所有常见名称冲突。

这是一个工作示例(使用 gfortran 4.9 测试)。

module Namespace_Foo_M
implicit none

type :: Namespace_Foo
  integer :: bar
  real    :: bar_baz
  contains
  procedure, pass(this) :: search => Namespace_Foo_search
end type

contains

function Namespace_Foo_search(this, offset) result(index)
  class(Namespace_Foo) :: this 
  integer,intent(in)   :: offset !input
  integer              :: index  !return value
  index = this%bar + int(this%bar_baz) + offset
end function

end module

program main
use Namespace_Foo_M !src/Namespace/Foo_M.f90

type(Namespace_Foo) :: foo

foo % bar = 1
foo % bar_baz = 7.3

print *, foo % search(3) !should print 11

end program

请注意,为了运行示例,您可以将以上所有内容复制/粘贴到一个文件中。

最后的想法

我发现 Fortran 中缺少命名空间非常令人沮丧,破解它的唯一方法就是将其包含在名称本身中。我们有一些嵌套的“命名空间”,例如在 C++ Utils::IO::PrettyPrinter 和 Fortran 中 Utils_IO_PrettyPrinter。我使用 CamelCase 上课的原因之一,例如PrettyPrinter 而不是 Pretty_Printer,是为了消除命名空间的歧义。命名空间是大写还是小写对我来说并不重要,但是在名称和文件路径中应该使用相同的大小写,例如班级utils_io_PrettyPrinter 应该住在utils/io/PrettyPrinter_M.f90。在大型/不熟悉的项目中,您将花费大量时间搜索源代码树以查找特定模块所在的位置,并且在模块名称和文件路径之间制定约定可以节省大量时间。

【讨论】:

以上是关于在 fortran 中命名派生类型的良好做法的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Fortran 派生类型或类中实现类型绑定写入语句输出

作为派生数据类型的组件的命名常量

Fortran 派生类型

确定内存中的 Fortran 派生类型大小

Fortran 派生类型包含可从 C 访问的指针

在 Fortran 90 中使用二维数组与派生类型数组