【发布时间】:2023-01-18 23:56:30
【问题描述】:
我发现了类型绑定过程,并且想知道如何使用它们。我有按预期工作的代码:
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。
下面的代码不使用类型绑定过程,可以满足我的要求,但不确定是否可行。第二种方法有什么缺陷吗?
非常感谢
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
澄清
正如 cmets 中指出的那样,前面的示例可能没有用。这是我认为可以做我想要的并且可以扩展到我的真实代码的代码:
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 将是一个数组,这样数组的每个组件将根据用户输入保存不同的过程。
【问题讨论】:
-
“现在我不知道如何在运行时分配 initval 和 writeval,如果有任何意义的话。”这取决于您要如何使用这些过程。在您展示的示例程序中,这样做意义不大,但在其他情况下却很有意义。你希望有多通用/灵活?
-
@fracescalus 谢谢。如果不发布另一个更长的示例,我不确定如何更好地解释。我希望能够根据用户输入选择指向一个或另一个子例程。子例程将具有相同的参数,但会做不同的事情。这些子例程将取决于不同的参数以及派生类型中托管的值。重点是避免在整个代码中使用条件语句,并为子例程使用通用名称。您认为代码 2 可以接受吗?
-
好吧,你总是可以使用函数指针,就像你在上一个例子中所做的那样。但是函数指针与类型绑定过程不同。那么,你真正的问题是你最后在样本中做了什么吗?用函数指针的方案是否可行?这与您在帖子第一部分中显示的内容非常不同。
标签: pointers interface fortran