将派生类型与过程从模块放入子模块 [英] Puting derived types with procedures from module to submodule

查看:65
本文介绍了将派生类型与过程从模块放入子模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于使用子模块,我需要一些帮助.我的意图是将一个子模块用于父模块的特定派生类型,并且我想将派生类型的整个声明放入子模块中.例如,这是我要转换的示例代码:

I need a little help about using submodules. My intention is to use one submodule for specific derived type from parent module and I want to put the whole declaration of the derived type into the submodule. For example, this is my example code which I want to transform:

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

是否可以在子模块中使用派生类型(包括组件和过程)?例如,通过这种方式:

Is there way for using a derived type(with components and procedures) in a submodule? For example, in this way:

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

在这种情况下,我不能在主程序中使用指针和目标变量,而我想这样做,或者是否有可能在PARENT_MODULE中声明指针和目标变量.

In this case I can not use pointer and target variable in main program and I want to do that or if it is possible to make declaration of pointer and target variable in PARENT_MODULE.

我的IDE是使用Gfortran编译器的Code :: Blocks 17.12.编译器的版本是:MinGW 6.3.0.

My IDE is Code::Blocks 17.12 with Gfortran compiler. The version of compiler is: MinGW 6.3.0.

推荐答案

是否可以在子模块中使用派生类型(包括组件和过程)?

Is there way for using a derived type(with components and procedures) in a submodule?

简短答案:. (至少不是您的期望)

Short answer: no. (At least not how your are expecting to)

子模块是该语言中添加的一项功能,用于解决一个特定的问题:接口与实现的分离.主要的动机是当您只需要更改模块中的实现细节时生成的编译级联.

Submodules are a feature added to the language to address one specific question: separation of interface and implementation. The main motivation was the compile cascades generated when you needed to change just a implementation detail in a module.

但是子模块不是模块!

子模块与模块绑定,并为该模块中声明的过程提供实现.因此,子模块可以访问其父模块中的所有声明.但是,该模块对其子模块一无所知,也不会像子模块那样使用它的子模块.该模块只是希望您在链接时添加子模块,足以覆盖所有缺少的过程实现.

A submodule is tied to a module and provides implementation to procedures declared in that module. So, a submodule have access to all declarations in it's parent module. Nonetheless, the module doesn't know anything about it's Submodules, and doesn't USE it's Submodules like they were modules. The module just expect you to add Submodules at link time, enough to cover all the missing procedure implementations.

因此,如果您要在子模块中声明类型或其他任何类型,则它对于父模块将是本地的并且是不透明的.

So, if you would declare a type or anything else in a submodule, it would be local and opaque to the parent module.

如果需要通过另一个单元中的主机访问程序统一的声明,则需要使用模块.

If you need to access declarations of a program unity by host in another unit, a Module is what you need.

您必须明智地设计解决方案.按主题和依赖项将模块分开.如果三种类型相互引用,那么它们之间的相关性就应该在同一程序单元中.

You have to design your solution wisely. Separate your modules by subject and dependency. If three types reference each other then they are very related should be in the same program unit.

这篇关于将派生类型与过程从模块放入子模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆