我试图隐藏真实数据类型和复杂数据类型之间的区别。在FORTRAN 2003中,我认为有办法做到这一点。
目标是定义一个多态可分配数组,它的类型可以在运行时决定。此外,还有一个子例程,它使用多态数组来做一些代数(同样的方程适用于实数据和复杂数据)。
为了做到这一点,我做了两次尝试:
办法A:
module poly
implicit none
private
type, abstract, public :: MyType
contains
procedure, public :: Constructor
endtype MyType
type, extends(MyType), public :: MyTypeR
real(8), allocatable :: AllData(:)
endtype MyTypeR
type, extends(MyType), public :: MyTypeI
complex(8), allocatable :: AllData(:)
endtype MyTypeI
contains
subroutine Constructor(this, Nsize)
class(MyType), intent(inout) :: this
integer, intent(in) :: Nsize
select type(this)
type is(MyTypeR)
allocate(this%AllData(Nsize))
type is(MyTypeI)
allocate(this%AllData(Nsize))
endselect
endsubroutine
endmodule poly
! Algebra subroutine
module Operation
contains
subroutine Square(Array)
class(*), intent(inout) :: Array(:)
select type(Array)
class is(real(8))
Array = Array**2
class is(complex(8))
Array = Array**2
endselect
endsubroutine Square
endmodule Operation
! Main
program test
use poly
use Operation
class(MyType), allocatable :: t1, t2
integer :: i
logical :: IfComplex = .true.
if(IfComplex) then
allocate(MyTypeI::t1)
else
allocate(MyTypeR::t1)
endif
call t1%Constructor(4)
call Square(t1%AllData)
endprogram test方法B(无限多态可分配变量):
module poly
implicit none
private
type, public :: MyType
class(*), allocatable :: AllData(:)
contains
procedure, public :: Constructor
endtype MyType
contains
subroutine Constructor(this, Nsize, IfComplex)
class(MyType), intent(inout) :: this
integer, intent(in) :: Nsize
logical, intent(in) :: IfComplex
if(IfComplex) then
allocate(complex(8)::this%AllData(Nsize))
else
allocate(real(8)::this%AllData(Nsize))
endif
endsubroutine
endmodule poly
! Same algebra subroutine
! Main
program test
use poly
use Operation
type(MyType) :: t1, t2
integer :: i
call t1%Constructor(4, .true.)
call Square(t1%AllData)
endprogram test那么,在这两种方法中,我的代数子例程都有问题:在内部赋值语句中,变量不应该是多态的。如有任何建议,将不胜感激。
发布于 2014-09-24 02:10:12
有几个问题。
在当前的Fortran中,不能扩展内部类型--内部类型不能出现在派生类型定义中的扩展说明符中。
因此,在Fortran 2008中,语言禁止假装内部类型可以是select类型构造中的祖先类型。这种禁止隐含在类型保护语句的语法规则中(类型是.类是,以此类推-类是类型保护的形式-stmt明确限制在派生类型规范(不包括内部类型名称的使用),这意味着符合Fortran 2008编译器应该为您的语法发出错误消息。
(这个限制在Fortran 2003中并不存在,但它是在后来的Fortran 2003更正中添加的--也许您的Fortran 2003编译器供应商还没有准备好实现它。)
在Fortran 2003中,当变量被分配给(等于的左手边的东西)多态时,不允许内部赋值。为多态变量赋值的能力是Fortran 2008中添加到语言中的一个特性。
以上两种问题的解决方案都是使Square子例程类型中的类型保护语句是“是”而不是“类”。
除了眼前的问题(以下内容更主观,取决于您最终计划做什么):
https://stackoverflow.com/questions/26000669
复制相似问题