Fortran 将带有过程的派生类型从模块放到子模块
我需要一些关于使用子模块的帮助。我的意图是为父模块的特定派生类型使用一个子模块,我希望将派生类型的整个声明放入子模块中。例如,这是我想要转换的示例代码:Fortran 将带有过程的派生类型从模块放到子模块,fortran,Fortran,我需要一些关于使用子模块的帮助。我的意图是为父模块的特定派生类型使用一个子模块,我希望将派生类型的整个声明放入子模块中。例如,这是我想要转换的示例代码: MODULE PARENT_MODULE IMPLICIT NONE TYPE , PUBLIC :: DERIVED_TYPE_A PRIVATE INTEGER :: I_00 CONTAINS PROCEDURE , PUBLIC :: CALC_I_00 => CALC_DATA_I_00 PROC
MODULE PARENT_MODULE
IMPLICIT NONE
TYPE , PUBLIC :: DERIVED_TYPE_A
PRIVATE
INTEGER :: I_00
CONTAINS
PROCEDURE , PUBLIC :: CALC_I_00 => CALC_DATA_I_00
PROCEDURE , PUBLIC :: TAKE_I_00 => TAKE_DATA_I_00
END TYPE DERIVED_TYPE_A
PRIVATE :: CALC_DATA_I_00
PRIVATE :: TAKE_DATA_I_00
INTERFACE
MODULE SUBROUTINE CALC_DATA_I_00( THIS , NUM_00 )
CLASS( DERIVED_TYPE_A ) :: THIS
INTEGER , INTENT( IN ) :: NUM_00
END SUBROUTINE CALC_DATA_I_00
MODULE FUNCTION TAKE_DATA_I_00( THIS ) RESULT( RES )
CLASS( DERIVED_TYPE_A ) :: THIS
INTEGER :: RES
END FUNCTION TAKE_DATA_I_00
END INTERFACE
END MODULE PARENT_MODULE
SUBMODULE( PARENT_MODULE ) TYPE_A
CONTAINS
MODULE PROCEDURE CALC_DATA_I_00
THIS%I_00 = NUM_00 + 2
END PROCEDURE CALC_DATA_I_00
MODULE PROCEDURE TAKE_DATA_I_00
RES = THIS%I_00
END PROCEDURE TAKE_DATA_I_00
END SUBMODULE TYPE_A
PROGRAM TYPE_SUBMODULES
USE , NON_INTRINSIC :: PARENT_MODULE
IMPLICIT NONE
INTEGER :: I
CLASS( DERIVED_TYPE_A) , POINTER :: P_ARR_INT
TYPE( DERIVED_TYPE_A ) , DIMENSION( 3 ) , TARGET :: ARR_INT
D00: DO I = 1 , 3
P_ARR_INT => ARR_INT( I )
CALL P_ARR_INT%CALC_I_00( I )
WRITE( * , * ) ARR_INT( I )%TAKE_I_00()
END DO D00
END PROGRAM TYPE_SUBMODULES
有没有办法在子模块中使用派生类型(包含组件和过程)?例如,通过这种方式:
SUBMODULE( PARENT_MODULE ) TYPE_A
TYPE :: D_TYPE_A
INTEGER :: I_00
CONTAINS
! PROCEDURE :: CALC_I_00 => CALC_DATA_I_00
! PROCEDURE :: TAKE_I_00 => TAKE_DATA_I_00
END TYPE D_TYPE_A
CLASS( D_TYPE_A ) , POINTER :: P_ARR_INT
TYPE( DERIVED_TYPE_A ) , DIMENSION( 3 ) , TARGET :: ARR_INT
CONTAINS
!MODULE SUBROUTINE CALC_DATA_I_00( THIS )
!
! CLASS( D_TYPE_A ) :: THIS
! ! INTEGER , INTENT( IN ) :: NUM_00
!
! THIS%I_00 = NUM_00 + 1
!
!END SUBROUTINE CALC_DATA_I_00
!
!!FUNCTION TAKE_DATA_I_00( THIS ) RESULT( RES_00 )
!!
!! CLASS( D_TYPE_A ) :: THIS
!! INTEGER :: RES_00
!!
!! RES_00 = THIS%I_00
!!
!!END FUNCTION TAKE_DATA_I_00
END SUBMODULE TYPE_A
在这种情况下,我不能在主程序中使用指针和目标变量,我想这样做,或者如果可以在父模块中声明指针和目标变量
我的IDE是带有Gfortran编译器的代码::Blocks 17.12。编译器的版本为:mingw6.3.0
有没有办法在子模块中使用派生类型(包含组件和过程)
简短回答:否。(至少不是你期望的那样)
子模块是添加到语言中的一个特性,用于解决一个特定问题:接口和实现的分离。主要动机是当您只需要更改模块中的实现细节时生成的编译级联
但是子模块不是模块
子模块绑定到一个模块,并为该模块中声明的过程提供实现。因此,子模块可以访问其父模块中的所有声明。尽管如此,模块对它的子模块一无所知,也不会像使用模块一样使用它的子模块。该模块只希望您在链接时添加子模块,足以覆盖所有缺失的过程实现
因此,如果您要在子模块中声明一个类型或任何其他内容,它将是本地的,对父模块来说是不透明的
如果需要通过另一个单元中的主机访问程序统一性声明,则需要一个模块
你必须明智地设计你的解决方案。按主题和依赖项分离模块。如果三种类型相互引用,那么它们应该在同一个程序单元中非常相关。只需计算您有多少问题:1)如何(以及为什么)使用子模块,2)如何避免为每种类型创建单个文件(与子模块无关)?3) 可以在子模块中使用private和public吗?4) 是否可以使用没有显式接口的过程?5) 如何在父模块中使用接口块?6) 如何使类型为private的元素?7) 如何公开类型程序?如果你想让你的问题得到任何关注,你需要集中注意力。我支持这一点。事实上,我们有太多的理由来结束这些问题。请在每篇文章中问一个问题。@VladimirF我需要问一个新问题还是重新格式化现有的问题?你可以重新格式化这个问题。@VladimirF如果我有34个派生类型,我需要在派生类型编号32的过程中使用派生类型编号16,或者如果我需要使用相同意义的指针,等等……如果我把每一个派生类型在项目中的单独文件中,在某些阶段,我遇到了循环依赖的问题。