我主要是用Python进行科学编程,并且没有大量的Fortran(90/95)经验。对于我的一个项目,我想定义一个派生类型,并为该类型重载一堆运算符。至关重要的是,我希望派生类型的变量之一为可变长度的数组。至少,我在代码的不同部分需要两个不同的长度。如何才能最好地有效地做到这一点并避免代码重复?
我的第一种方法是使用可分配的数组,但是该方法涉及整个代码中的多个分配语句,包括重载的运算符。这也导致在MPI应用程序中使用代码时遇到困难。
我当前的方法是两个在两个单独的模块中定义一个具有相同名称的类型,并在代码的不同部分使用一个或另一个。可以使用头文件(在下面的示例中为mytype_operators.h
)共享重载的运算符。
module mod1
type mytype
real :: x1
real,dimension(1) :: x2
end type mytype
#include "mytype_operators.h"
end module mod1
module mod2
type mytype
real :: x1
real,dimension(10) :: x2
end type mytype
#include "mytype_operators.h"
end module mod2
不幸的是,代码中有一个模块带有我要对两种类型使用的子例程。目前,我有该代码的两个副本。一个带有“ use mod1
”,另一个带有“ use mod2
”。我可以改善这一点并避免代码重复吗?
答案 0 :(得分:1)
您的案例非常适合使用2003年标准中引入的Fortran功能(后来被编译器采用),名为parameterized derived types。首先,您应该检查编译器的符合性状态,以了解其是否完全受支持。
此功能允许您在声明或构造派生类型时传递自定义参数,因此将相应地调整内部功能。它们有利于将不同的行为替代方案分组在一个类型名称中,可能会有相当大的编码或存储差异。参数有2种类型:
kind
参数的行为与内在类型的种类说明符非常相似。所有变量的种类参数在编译时都必须知道,并且实际上被视为常量。便利之处在于,您可以通过仅更改声明或构造中的值来轻松地(在代码时间中)更改它。通常用于专门说明内在类型的组件的类型。len
参数的行为很像固有字符类型的len说明符。您可以在编译时或运行时定义len参数,并且变量的len参数除非声明为可分配的,否则不能更改。此外,您可以在过程中使用带有假定len参数的参数,并避免代码冗长。通常将它用作派生类型的“长度”或“维度”参数,因为您可以在数组边界和字符长度的声明中使用它们。通常,类型参数用于模仿派生类型中内在类型的功能,但您也可以获取“创意”并将其用于其他事物,例如转换矩阵类型的维空间;例如,用于自定义“联合类型”(如枚举);因为“计量单位”数据类型中的物理量的性质(标有“质量”单位的实际值与“温度”单位不直接兼容,但是可以用相同的方式处理它们)码);元组类型的“ arity” ...
module mod1
type :: mytype(n)
integer, len :: n
real :: x1
real, dimension(n) :: x2
end type mytype
contains
! your operations here...
end module mod1
并像这样使用它:
program test_pdt
use mod1
implicit none
type(mytype(10)) :: mt10
type(mytype(1)) :: mt1
integer :: i
mt10%x1 = 40.0
mt10%x2 = [(0.5 * i, i = 1, 10)]
mt1 = mytype(1)(20.0, [30.0])
call sub(mt10)
call sub1(mt1)
contains
subroutine sub(m)
! accepts values with any "n" parameter
type(mytype(*)) :: m
! you can also use them in declarations
integer, dimension(m%n + 1) :: y
type(mytype(m%n)) :: w
print *, m%n, w%n, size(y)
end
subroutine sub1(m)
type(mytype(1)) :: m ! only accepts values with n=1
print *, m%x1, m%x2, m%n
end
end
警告: 尽管已在很多年前宣布了此功能,但最近才将其添加到大多数编译器中,并且您应该意识到实现中仍然存在一些错误。常规使用可能应该没问题,但是在某些特殊情况下,有时甚至是ICE,我经常会遇到错误的语法错误。