是否有一种方法可以有条件地设置公共数据结构的类型?



是否有一种方法可以有条件地设置公共数据结构?

例如:

MODULE EXAMPLE
USE DATA_TYPE_Define, ONLY: DATA_TYPE_A, DATA_TYPE_B
USE PARAMETER,        ONLY: CaseAisTrue
! Disable all implicit typing
IMPLICIT NONE
! ------------
! Visibilities
! ------------
! Everything private by default
PRIVATE
! The shared data
PUBLIC :: DATA
! ------------------------------------------------
! The shared data 
! ------------------------------------------------
IF (CaseAisTrue) Then
TYPE(DATA_TYPE_A), SAVE :: DATA
ELSE
TYPE(DATA_TYPE_B), SAVE :: DATA
END IF

CONTAINS
...

其中DATA_TYPE_A和DATA_TYPE_B是两个不同的数据结构/派生类型。

除了引入更多的公共变量之外,还有什么好的方法来设置这个吗?

谢谢!

我看到两个选项

  1. 可以在运行时更改吗?然后,您可能需要在代码的其他任何地方访问相同的DATA的唯一原因是因为DATA_TYPE_ADATA_TYPE_B具有本质上相同的API。这是一个典型的面向对象编程模式:您希望这两种数据类型共享相同的API:
! The base class
type, abstract, public :: DATA_TYPE
end type DATA_TYPE
type, public, extends(DATA_TYPE) :: DATA_TYPE_A
[...]
end type DATA_TYPE_A
type, public, extends(DATA_TYPE) :: DATA_TYPE_B
[...]
end type DATA_TYPE_B

如果你需要在你访问的数据类型之间切换,你可以为它们设置两个单独的变量:

! Actual shared data, here or elsewhere
type(DATA_TYPE_A), target, SAVE :: DATA_A
type(DATA_TYPE_B), target, SAVE :: DATA_B

并使用指针指向它们:

class(DATA_TYPE), public, pointer :: DATA => null()
! Set pointer
subroutine set_data(mode)
integer, intent(in) :: mode
select case (mode)
case (1);     DATA => DATA_A
case (2);     DATA => DATA_B
case default; nullify(DATA)
end select  
end subroutine set_data

否则,如果您不经常更改它,您可以使用多态分配,这将更优雅:

! Actual shared data
class(DATA_TYPE), allocatable :: DATA

并在需要时分配正确的类型:

! Polymorphic allocation
subroutine set_data(mode)
integer, intent(in) :: mode
integer :: ierr

! Deallocate first
deallocate(DATA,stat=ierr) ! don't stop if not already allocated
select case (mode)
case (1);     allocate(DATA,source=DATA_A) 
case (2);     allocate(DATA,source=DATA_B)
case default; return
end select  
end subroutine set_data
  1. 应该在编译时修复(parameter化)吗?然后,编译器预处理器将是最有用的。例如,使用C预处理器,您将拥有:

#define DATATYPE_IS_A

#ifdef DATATYPE_IS_A
type(DATA_TYPE_A), parameter :: DATA = [...]
#else
type(DATA_TYPE_B), parameter :: DATA = [...]
#endif

后一个选项在编译之前执行,也就是说,该数据类型是强制的,永远不能更改。

相关内容

  • 没有找到相关文章

最新更新