在 Fortran 中创建异构数组
Creating heterogeneous arrays in Fortran
我正在尝试创建包含不同类型变量的异构数组,例如 [ 1.0, 7, "hi" ]
。我试图在数组构造函数中包含 class(*)
或 type(*)
(请参阅以下代码的末尾),但 gfortran5.2 只是将其视为语法错误。有什么方法可以用数组构造函数创建这样的数组,还是有必要使用不同的方法(例如,定义一个单独包含每个元素的类型)?
更多详情:
下面的代码是我为什么要创建这样一个数组的一个例子。 checktype_multi
例程使用 optional
关键字接收多个参数,但由于参数数量固定,这种方法显然受到限制。为了允许任意数量的参数,我尝试了 checktype_array
例程,但似乎无法传递具有不同类型的数组......更实用的 可能是制作一个用于打印变量的子例程各种类型的参数数量。
module mymod
implicit none
contains
subroutine checktype ( x )
class(*) :: x
select type ( x )
type is ( integer ) ; print *, "int : ", x
type is ( real ) ; print *, "real : ", x
type is ( character(*) ) ; print *, "string : ", x
endselect
end subroutine
subroutine checktype_multi ( x1, x2, x3 )
class(*), optional :: x1, x2, x3
print *
if ( present( x1 ) ) call checktype ( x1 )
if ( present( x2 ) ) call checktype ( x2 )
if ( present( x3 ) ) call checktype ( x3 )
end subroutine
subroutine checktype_array ( a )
class(*) :: a(:)
integer :: k
print *
do k = 1, size( a )
call checktype ( a( k ) )
enddo
end subroutine
end module
program main
use mymod
call checktype_multi ( 1.0 )
call checktype_multi ( 1.0, 7 )
call checktype_multi ( 1.0, 7, "hi" )
! call checktype_array ( [ 1.0, 7, "hi" ] ) !! error (this is to be expected)
!>>> Here is the problem.
! call checktype_array ( [ type(*) :: 1.0, 7, "hi" ] ) !! this is also an error
! call checktype_array ( [ class(*) :: 1.0, 7, "hi" ] ) !! this too
end program
数组的元素只能在值上有所不同。它们在类型或任何其他属性上不能不同。
相反,使用派生类型包装器围绕无限多态可分配组件。然后将组件的动态类型视为包装类型对象值的一部分。
TYPE :: wrapper
CLASS(*), ALLOCATABLE :: item
END TYPE wrapper
CALL sub([wrapper(1), wrapper(2.0), wrapper('3')])
(数组构造函数(或结构构造函数)指定一个值。值本身不能是多态的,值的类型始终只是值的类型。可选前导的语法 type数组构造函数中的 -spec 反映了这一点,因为它只是一个 type-spec,而不是 declaration-type-spec.)
我正在尝试创建包含不同类型变量的异构数组,例如 [ 1.0, 7, "hi" ]
。我试图在数组构造函数中包含 class(*)
或 type(*)
(请参阅以下代码的末尾),但 gfortran5.2 只是将其视为语法错误。有什么方法可以用数组构造函数创建这样的数组,还是有必要使用不同的方法(例如,定义一个单独包含每个元素的类型)?
更多详情:
下面的代码是我为什么要创建这样一个数组的一个例子。 checktype_multi
例程使用 optional
关键字接收多个参数,但由于参数数量固定,这种方法显然受到限制。为了允许任意数量的参数,我尝试了 checktype_array
例程,但似乎无法传递具有不同类型的数组......更实用的
module mymod
implicit none
contains
subroutine checktype ( x )
class(*) :: x
select type ( x )
type is ( integer ) ; print *, "int : ", x
type is ( real ) ; print *, "real : ", x
type is ( character(*) ) ; print *, "string : ", x
endselect
end subroutine
subroutine checktype_multi ( x1, x2, x3 )
class(*), optional :: x1, x2, x3
print *
if ( present( x1 ) ) call checktype ( x1 )
if ( present( x2 ) ) call checktype ( x2 )
if ( present( x3 ) ) call checktype ( x3 )
end subroutine
subroutine checktype_array ( a )
class(*) :: a(:)
integer :: k
print *
do k = 1, size( a )
call checktype ( a( k ) )
enddo
end subroutine
end module
program main
use mymod
call checktype_multi ( 1.0 )
call checktype_multi ( 1.0, 7 )
call checktype_multi ( 1.0, 7, "hi" )
! call checktype_array ( [ 1.0, 7, "hi" ] ) !! error (this is to be expected)
!>>> Here is the problem.
! call checktype_array ( [ type(*) :: 1.0, 7, "hi" ] ) !! this is also an error
! call checktype_array ( [ class(*) :: 1.0, 7, "hi" ] ) !! this too
end program
数组的元素只能在值上有所不同。它们在类型或任何其他属性上不能不同。
相反,使用派生类型包装器围绕无限多态可分配组件。然后将组件的动态类型视为包装类型对象值的一部分。
TYPE :: wrapper
CLASS(*), ALLOCATABLE :: item
END TYPE wrapper
CALL sub([wrapper(1), wrapper(2.0), wrapper('3')])
(数组构造函数(或结构构造函数)指定一个值。值本身不能是多态的,值的类型始终只是值的类型。可选前导的语法 type数组构造函数中的 -spec 反映了这一点,因为它只是一个 type-spec,而不是 declaration-type-spec.)