在 Fortran 中创建异构数组 [英] Creating heterogeneous arrays in Fortran

查看:20
本文介绍了在 Fortran 中创建异构数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建包含不同类型变量的异构数组,例如 [ 1.0, 7, "hi" ].我试图在数组构造函数中包含 class(*)type(*)(请参见下面代码的结尾),但 gfortran5.2 只是简单地将其视为语法错误.有没有什么办法可以用数组构造函数来制作这样的数组,或者是否需要使用不同的方法(例如,分别定义一个包含每个元素的类型)?

I am trying to create heterogeneous arrays that contain variables of different types, for example, [ 1.0, 7, "hi" ]. I tried to include class(*) or type(*) in the array constructor (please see the end of the following code), but gfortran5.2 simply regards it as syntax error. Is there any way to make such an array with array constructor, or is it necessary to use a different approach (e.g., define a type that contains each element separately)?

更多详情:

以下代码是我为什么要创建这样一个数组的示例.checktype_multi 例程使用 optional 关键字接收多个参数,但由于参数数量固定,这种方法显然受到限制.为了允许任意数量的参数,我尝试了 checktype_array 例程,但似乎无法传递不同类型的数组......更实用的 case 可能是制作一个子程序来打印可变数量的各种类型的参数.

The following code is an example why I want to create such an array. The checktype_multi routine receives multiple arguments with the optional keyword, but this approach is clearly limited because of the fixed number of arguments. To allow arbitrary number of arguments, I tried the checktype_array routine, but it seems not possible to pass an array with different types... A more practical case may be to make a subroutine for printing a variable number of arguments with various types.

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

推荐答案

数组的元素只能在值上不同.它们的类型或任何其他属性不能不同.

The elements of an array may only differ from each other in value. They cannot differ in type, or any other attribute.

相反,在无限多态可分配组件周围使用派生类型包装器.然后,组件的动态类型被视为包装器类型对象值的一部分.

Instead, use a derived type wrapper around an unlimited polymorphic allocatable component. The dynamic type of the component is then considered part of the value of the object of the wrapper type.

TYPE :: wrapper
  CLASS(*), ALLOCATABLE :: item
END TYPE wrapper

CALL sub([wrapper(1), wrapper(2.0), wrapper('3')])

(数组构造函数(或结构构造函数)指定一个值.值本身不能是多态的,值的类型始终只是值的类型.可选前导type-spec的语法em> 在数组构造函数中反映了这一点,因为它只是一个 type-spec,而不是一个 declaration-type-spec.)

(An array constructor (or structure constructor) specifies a value. A value itself cannot be polymorphic, the type of the value is always just the type of the value. The syntax for optional leading type-spec in an array constructor reflects this, in that it is just a type-spec, not a declaration-type-spec.)

这篇关于在 Fortran 中创建异构数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆