
[英]fortran 90 allocatable array already allocated on calling type bound procedure
[英]Is it possible in Fortran to assign procedure name at run time in a type bound procedure?
我发现了类型绑定过程,并且想知道如何使用它们。 我有按预期工作的代码:
module utils
implicit none
type TypeParam
integer :: val
contains
procedure :: initval => initI
procedure :: writeval => writeI
end type TypeParam
contains
!---------------------------
subroutine initI(this,val)
class(TypeParam),intent(inout)::this
integer,intent(in) :: val
this%val=val
end subroutine initI
!---------------------------
subroutine writeI(this)
class(TypeParam),intent(inout)::this
print*,this%val
end subroutine writeI
!---------------------------
end module utils
program testtypebound
use utils
implicit none
type(TypeParam) :: TP(2)
call TP(1)%initval(3)
call TP(2)%initval(5)
call TP(1)%writeval() ! Returns 3
call TP(2)%writeval() ! Returns 5
end program testtypebound
现在我不知道如何在运行时分配 initval 和 writeval,如果它有任何意义的话。 让它们指向 null() 并在主程序中将它们分配为 TP(1)%initval=>othersubroutine。
下面的代码不使用类型绑定过程,它执行我想要的操作,但不确定它是否是通往 go 的方式。第二种方法是否有任何缺陷?
非常感谢
module utils
implicit none
type TypeParam
integer :: val
procedure(InitValInteger), pointer :: initval => null()
procedure(WriteValInteger), pointer :: writeval => null()
end type TypeParam
interface
subroutine InitValInteger(this,val)
import TypeParam
class(TypeParam),intent(inout)::this
integer,intent(in) :: val
end subroutine InitValInteger
subroutine WriteValInteger(this)
import TypeParam
class(TypeParam),intent(inout)::this
end subroutine WriteValInteger
end interface
contains
!---------------------------
subroutine initI(this,val)
class(TypeParam),intent(inout)::this
integer,intent(in) :: val
this%val=val
end subroutine initI
!---------------------------
subroutine writeI(this)
class(TypeParam),intent(inout)::this
print*,this%val
end subroutine writeI
!---------------------------
end module utils
program testtypebound
use utils
implicit none
type(TypeParam) :: TP(2)
TP(1)%initval =>initI
TP(1)%writeval=>writeI
TP(2)%initval =>initI
TP(2)%writeval=>writeI
call TP(1)%initval(3)
call TP(2)%initval(5)
call TP(1)%writeval() ! Returns 3
call TP(2)%writeval() ! Returns 5
end program testtypebound
澄清
正如评论中指出的那样,前面的示例可能没有用。 这是我认为可以做我想要的并且可以扩展到我的真实代码的代码:
module utils
implicit none
type TypeParam
integer :: val
procedure(UseValue), pointer :: useval => null()
end type TypeParam
interface
real*8 function UseValue(this,i)
import TypeParam
class(TypeParam),intent(inout)::this
integer,intent(in) :: i
end function UseValue
end interface
contains
!---------------------------
real*8 function useval1(this,i)
class(TypeParam),intent(inout)::this
integer,intent(in) :: i
useval1=this%val+i
end function useval1
!---------------------------
real*8 function useval2(this,i)
class(TypeParam),intent(inout)::this
integer,intent(in) :: i
useval2=this%val**2+i
end function useval2
!---------------------------
end module utils
program testtypebound
use utils
implicit none
integer :: i
type(TypeParam) :: TP
write(*,*) "Enter version 1 or 2"
read(*,*) i
if(i==1)then
TP%val=2
TP%useval =>useval1
elseif(i==2)then
TP%val=1
TP%useval =>useval2
else
write(*,*) "Version unknown (1 or 2)"
stop
endif
print*, TP%useval(2) ! Returns 4 if i=1 and 3 if i=2
end program testtypebound
但在我开始实施之前,这段代码是否有缺点、缺陷? 可以使用类型绑定过程使其更简单/更紧凑吗? 在现实生活中,TP 将是一个数组,这样数组的每个组件将根据用户输入保存不同的过程。
类型绑定过程“绑定到派生类型并通过该类型的 object 引用”(Fortran 2018,3.112.6)。 绑定到一个类型而不是object意味着相同类型的两个对象产生相同的引用。 (此外,类型的定义在执行期间不能更改。)
过程指针组件不同:它是类型的组件,类型的每个 object 实例都可以有自己的值,对于变量,其值可以在执行期间更改。
哪种机制最适合用例取决于需要什么。 如果您希望相同类型的两个对象解析为不同的过程引用,或者希望引用的过程在执行过程中发生变化,您将使用过程指针组件。
过程指针可以不关联,并且类型绑定过程没有等效的 state。 这意味着您有责任确保call a%s()
具有与目标关联的s
过程指针组件指针,但也允许您执行类似if (ASSOCIATED(a%s))...
逻辑(如果它是定义的关联状态)。 您还负责确保它始终指向您希望它指向的位置(另请注意,不能保护组件)并且为了方便起见,您最终可能会编写一个结构构造函数。
同样,过程指针组件可以以绑定名称不能使用的方式使用: call run(a%s)
允许用于过程指针组件,但不允许用于类型绑定过程。
也就是说,基于运行时条件的引用用例甚至可以使用类型绑定过程来解决:
type t
logical :: use_a = .TRUE.
contains
procedure :: selector
end type t
selector
是一个包装器
subroutine selector(this, val)
class(t), intent(in) :: this
integer, intent(in) :: val
if (this%use_a) then
call A(this, val)
else
call B(this, val)
end if
end subroutine selector
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.