首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Fortran中使用SubModules进行泛型赋值

在Fortran中使用SubModules进行泛型赋值
EN

Stack Overflow用户
提问于 2021-10-21 04:16:23
回答 1查看 74关注 0票数 1

如果我们有三个具有不同派生类型的不同文件,

MyTypeMod.f90:

代码语言:javascript
复制
MODULE MyTypeMod

TYPE, ABSTRACT :: MyType
INTEGER :: Num
END TYPE MyType

CONTAINS

END MODULE MyTypeMod

MyType1Mod.f90

代码语言:javascript
复制
MODULE MyType1Mod
USE MyTypeMod,  ONLY : MyType
USE MyType2Mod, ONLY : MyType2
IMPLICIT NONE

TYPE, EXTENDS(MyType) :: MyType1
CONTAINS
PROCEDURE :: Type1EqualsType2
GENERIC :: ASSIGNMENT(=) => Type1EqualsType2
END TYPE MyType1

CONTAINS

SUBROUTINE Type1EqualsType2(Type1, Type2)
TYPE(MyType1), INTENT(OUT) :: Type1
TYPE(MyType2), INTENT(IN) :: Type2
Type1%Num = Type2%Num
END SUBROUTINE Type1EqualsType2

END MODULE MyType1Mod

MyType2Mod.f90

代码语言:javascript
复制
MODULE MyType1Mod
USE MyTypeMod,  ONLY : MyType
USE MyType1Mod, ONLY : MyType1
IMPLICIT NONE

TYPE, EXTENDS(MyType) :: MyType2
CONTAINS
PROCEDURE :: Type2EqualsType1
GENERIC :: ASSIGNMENT(=) => Type2EqualsType1
END TYPE MyType2

CONTAINS

SUBROUTINE Type2EqualsType1(Type2, Type1)
TYPE(MyType2), INTENT(OUT) :: Type2
TYPE(MyType1), INTENT(IN) :: Type1
Type2%Num = Type1%Num
END SUBROUTINE Type2EqualsType1

END MODULE MyType2Mod

在这里,在这种情况下,由于模块文件相互依赖,我无法编译程序。我能用SubModules来解决这个问题吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-21 12:23:04

不幸的是,不,您不能完全按照您的要求使用子模块。这是因为两个函数Type1EqualsType2Type2EqualsType1在其函数接口中都需要MyType1MyType2。即使您使用子模块,这两个函数都必须在各自的模块中具有接口,因此循环依赖关系仍然存在。

然而,有几种可能的解决办法:

选择类型

这两个函数的intent(in)参数都可以是class(MyType),并且只能使用select type语句进行类型解析。这将允许您将函数定义移动到子模块并解析循环依赖,但也意味着您必须处理将扩展MyType的不同类型传递给函数的情况。而且,select type可能会慢一点,这取决于您的用例。

用于此的代码如下所示:

代码语言:javascript
复制
MODULE MyTypeMod
  IMPLICIT NONE
  TYPE, ABSTRACT :: MyType
    INTEGER :: Num
  END TYPE MyType
END MODULE MyTypeMod

MODULE MyType1Mod
  USE MyTypeMod, ONLY : MyType
  IMPLICIT NONE
  
  TYPE, EXTENDS(MyType) :: MyType1
  CONTAINS
    PROCEDURE :: Type1EqualsType2
    GENERIC :: ASSIGNMENT(=) => Type1EqualsType2
  END TYPE
  
  interface
    module SUBROUTINE Type1EqualsType2(this, input)
      TYPE(MyType1), INTENT(OUT) :: this
      class(MyType), INTENT(IN) :: input
    END SUBROUTINE
  end interface
END MODULE

MODULE MyType2Mod
  USE MyTypeMod, ONLY : MyType
  IMPLICIT NONE
  
  TYPE, EXTENDS(MyType) :: MyType2
  CONTAINS
    PROCEDURE :: Type2EqualsType1
    GENERIC :: ASSIGNMENT(=) => Type2EqualsType1
  END TYPE
  
  interface
    module SUBROUTINE Type2EqualsType1(this, input)
      TYPE(MyType2), INTENT(OUT) :: this
      class(MyType), INTENT(IN) :: input
    END SUBROUTINE
  end interface
END MODULE

submodule (MyType1Mod) MyType1Submod
  use MyType2Mod, only : MyType2
  implicit none
contains
  module procedure MyType1EqualsMyType2
    select type(input); type is(MyType1)
      this%Num = input%Num
    type is(MyType2)
      this%Num = input%Num
    class default
      ! Some kind of error handling goes here.
    end select
  end procedure
end submodule

submodule (MyType2Mod) MyType2Submod
  use MyType1Mod, only : MyType1
  implicit none
contains
  module procedure MyType2EqualsMyType1
    select type(input); type is(MyType1)
      this%Num = input%Num
    type is(MyType2)
      this%Num = input%Num
    class default
      ! Some kind of error handling goes here.
    end select
  end procedure
end submodule

通用程序

您可以将类型绑定的assignment(=)定义替换为泛型assignment(=)定义。这避免了运行时多态,但意味着您必须在一个新模块中定义赋值。

这看起来应该是:

代码语言:javascript
复制
MODULE MyTypeMod
  IMPLICIT NONE
  TYPE, ABSTRACT :: MyType
    INTEGER :: Num
  END TYPE MyType
END MODULE MyTypeMod

MODULE MyType1Mod
  USE MyTypeMod, ONLY : MyType
  IMPLICIT NONE
  
  TYPE, EXTENDS(MyType) :: MyType1
  END TYPE
END MODULE

MODULE MyType2Mod
  USE MyTypeMod, ONLY : MyType
  IMPLICIT NONE
  
  TYPE, EXTENDS(MyType) :: MyType2
  END TYPE
END MODULE

module MyEqualsMod
  use MyType1Mod : only MyType1
  use MyType2Mod : only MyType2
  implicit none
  
  interface assignment(=)
    module procedure MyType1EqualsMyType2
    module procedure MyType2EqualsMyType1
  end interface
contains
  subroutine MyType1EqualsMyType2(this,input)
    type(MyType1), intent(out) :: this
    type(MyType2), intent(in) :: input
    this%Num = input%Num
  end subroutine

  subroutine MyType2EqualsMyType1(this,input)
    type(MyType2), intent(out) :: this
    type(MyType1), intent(in) :: input
    this%Num = input%Num
  end subroutine
end module
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69655818

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档