Fortran 具有不同派生类型和关联过程的独立模块如何相互使用?
自由形式程序的模块采用从全局_模块开始的层次结构。然后,通道_模块和模式_模块都使用Global,工作正常。所有模块均采用Fortran 具有不同派生类型和关联过程的独立模块如何相互使用?,fortran,derived-types,Fortran,Derived Types,自由形式程序的模块采用从全局_模块开始的层次结构。然后,通道_模块和模式_模块都使用Global,工作正常。所有模块均采用隐式无。 我已将以下编译器错误隔离到Modes\u模块中Modes类型的关联初始化过程中的USE Channel\u Module语句 我确信DT的目的是通过相关程序彼此共享数据,但由于未知原因,在这种情况下它不起作用。全局和通道编译时都有0个错误和警告。通道和模式之前都可以从其全局父级访问数据。一切都是公开的。但是,我现在需要这两个同级通过作为类型或类传递来访问跨模块边界的
隐式无
。
我已将以下编译器错误隔离到Modes\u模块中Modes类型的关联初始化过程中的USE Channel\u Module
语句
我确信DT的目的是通过相关程序彼此共享数据,但由于未知原因,在这种情况下它不起作用。全局和通道编译时都有0个错误和警告。通道和模式之前都可以从其全局父级访问数据。一切都是公开的。但是,我现在需要这两个同级通过作为类型或类传递来访问跨模块边界的选定组件,但没有效果。我尝试将USE
限制为仅通道的DT,但这对编译结果没有影响。我想知道我是否遗漏了一些关于如何做到这一点的内容。
在这种情况下,派生类型交叉引用是如何实现的
使用英特尔(R)Visual Fortran编译器XE 12.0.4.196编译
[IA-32]。。。ifort/nologo/debug:full/Od/fpscomp:filesfromcmd
/警告:声明/警告:未使用/警告:截断\u源
/警告:接口/模块:“调试\”/对象:“调试\”
/Fd“Debug\vc90.pdb”/traceback/check:bounds/libs:static/threads
/dbglibs/c/Qvc9/Qlocation,链接,“c:\ProgramFiles(x86)\Microsoft
Visual Studio 9.0\VC\bin“”C:\Users\username\Documents\Visual Studio
2008\Projects\ELA\ELA\Modes\u Mdl.f90“
我认为下面的伪代码应该有助于澄清这个问题。通道先初始化,然后是模式。模式初始化成功后,通道%myArray将通过通道%calculatemyArray填充
在文件通道\u mdl.f90中:
MODULE Channel_MODULE
USE GLOBAL_MODULE !omitted for clarity
TYPE Channel_TYPE
! some vars
REAL, DIMENSION(3,12) :: myArray
LOGICAL :: populated = .false. !set to true in initChannel_Type
CONTAINS
PROCEDURE :: initialize => initChannel_Type !omitted for clarity
PROCEDURE :: calculatemyArray !to be Called following successful init of Modes, thus need to share info between these objects.
END TYPE Channel_TYPE
CONTAINS
LOGICAL FUNCTION calculatemyArray(this, Mds) !populate myArray
USE Modes_Module !need access to Modes%Qty array
IMPLICIT NONE
CLASS(Channel_Type), INTENT(INOUT) :: this
TYPE (Mode_Type), INTENT(IN) :: Mds
calculatemyArray = .true. !unless error occurs herein
! initialization process ...
END FUNCTION calculatemyArray
END MODULE Channel_Module
在文件模式下\u Mdl.f90
MODULE Modes_MODULE
USE GLOBAL_MODULE !omitted for clarity
TYPE Modes_TYPE
! some vars
INT(int16), ALLOCATABLE, DIMENSION(:) :: Qty
LOGICAL :: populated = .false.
CONTAINS
PROCEDURE :: initialize => initializeModes
END TYPE Modes_TYPE
CONTAINS
SUBROUTINE initializeModes(this, Srcs)
USE Channel_Module !need access to Srcs%Count to allocate Qty array
IMPLICIT NONE
CLASS(Modes_Type), INTENT(INOUT) :: this
TYPE (Channel_Type), INTENT(IN) :: Srcs
! initialization process ...
ALLOCATE(Qty(Srcs%Count))
populated = .true.
END SUBROUTINE initializeModes
END MODULE Modes_Module
在文件myPgm.f90中
Program foo
USE Channel_Module
USE Modes_Module
IMPLICIT NONE
TYPE (Channel_Type) :: Channels
TYPE (Mode_Type) :: Modes
Call Channels%initialize()
IF (Channels%populated) THEN
Call Modes%initialize(Channels)
! other statements & functions
END IF
END Program foo
你知道什么是悲伤的同时又是美好的吗?发现我想要的是阻止我得到我需要的。在上面的场景中,我认为如果我只传递通道的Count子组件值(INT),而不是整个通道对象(我认为我想要的),整个问题就会消失。
我仍然非常想知道如何在DT过程之间传递DT对象。这样做的方法似乎难以捉摸……你不能有循环依赖性(如果这是要求的话),但我们更明智地说,你应该展示你希望实现的代码(或至少接近代码)。因此,如果类型_B的关联过程不能使用伪参数引用它,那么它如何从类型_A访问数据?引用我的回答:“你必须明智地设计你的解决方案。按主题和依赖性分开你的模块。如果三种类型相互引用,那么它们非常相关,应该在同一个程序单元中。”直接将模式%Qty和Srcs%Count作为实际参数传递给类型绑定过程不是一个选项吗?(换句话说,除了第一个参数(“=”this“)外,使用基本数据类型而不是派生类型来定义后一个过程)另一种方法可能是将两个或多个类型(例如A_t和B_t)包含在一个模块中,包括“A_type.f90”、“B_type.f90”、“A_procs.f90”、“B_procs.f90”等(每个都包含类型和过程定义)。这允许不同类型的相互引用,但文件是分开的。我在程序的某些部分使用这种方法,但我想通常更建议使类型或模块耦合尽可能弱…例如。)