Fortran 派生类型

Posted

技术标签:

【中文标题】Fortran 派生类型【英文标题】:Fortran derived types 【发布时间】:2019-03-02 02:34:09 【问题描述】:

我想知道是否有可能在 Fortran 中定义一个派生类型,它会自动返回正确的类型,而无需专门调用该类型,例如var%real?这是一个解释我的意思的例子:

module DervType

  implicit none

  type, public :: mytype
    real(8) :: r
    integer :: i
    logical :: l
  end type

end module DervType

program TestType

  use DervType

  implicit none

  type(mytype) :: test

  test = 1.                   !! <-- I don't want to use test%r here

end program TestType

这是否可以通过定义某种接口分配(重载 =)或类似的东西来实现?这甚至可能吗?

谢谢!任何帮助表示赞赏!

【问题讨论】:

是的,可以定义分配。你可以试试看它是否符合你的要求吗?我想这与您的previous question 有关,但您可以在没有多态性的情况下执行此操作。 参见:this question。 但这是您问题的一个非常具体的方面。也就是说,test = x 可以这样做,以便test 集合的组件在某种程度上由x 的类型确定。然而,这就是你的意思吗? “自动返回正确类型”的部分表明您可能需要做一些更奇特的事情(比如 call sub(test) 的行为就像 call sub(test%r) 如果参数是真实的,等等)。 感谢您的回答!是的,我想这都是相关的,即使我放弃了其他东西......如果我编译上面的内容,我会得到:Error: Can't convert REAL(4) to TYPE(mytype),所以这不起作用。抱歉,我已经查看了您链接中的示例,但我不明白。我确实需要一个界面对吗? 所以我必须定义几个函数(实数、整数、逻辑)并通过接口分配它们?要试试看!谢谢! 【参考方案1】:

找到了一个解决方案,它实际上非常简单。代码如下:

module DervType

  implicit none

  type, public :: mytype
    real(8)                       :: r
    integer                       :: i
    character(len=:), allocatable :: c
    logical :: l
  end type

  interface assignment(=)                 // overload = 
    module procedure equal_func_class
  end interface

contains

  subroutine equal_func_class(a,b)

    implicit none

    type(mytype), intent(out) :: a
    class(*), intent(in)      :: b

    select type (b)
        type is (real)
            print *, "is real"
            a%r = b
        type is (integer)
            print *, "is int"
            a%i = b
        type is (character(len=*))
            print *, "is char"
            a%c = b
        type is (logical)
            print *, "is logical"
            a%l = b 
    end select

    return

  end subroutine equal_func_class  

end module DervType

program TestType

  use DervType

  implicit none

  type(mytype) :: test

  test = 1.      // assign real 
  test = 1       // assign integer
  test = "Hey"   // assign character
  test = .true.  // assign logical

  print *, "Value (real)      : ", test%r
  print *, "Value (integer)   : ", test%i
  print *, "Value (character) : ", test%c
  print *, "Value (logical)   : ", test%l

end program TestType

我现在正在尝试在程序中使用变量(例如,进行一些算术计算等),但这似乎相当困难,如果不是不可能的话。我可能会就此提出另一个问题。

【讨论】:

这是个坏主意。当有人引用test 时,您无法知道他们想要哪个值 - 实数、整数、逻辑或字符。因此,您的分配看起来与您的值访问不同,这令人困惑。 嗯,我想这取决于你想如何使用它。目前我同意这种情况,但这不是这个问题的一部分。我只是想知道如何或是否可以在不知道输入类型的情况下将值分配给延迟类型。目前我正在反方向工作。 实际上,在接口内包含许多过程的解决方案的优点是,如果您尝试分配未涵盖的类型,则会出现编译时错误。 Otoh,使用带有选择类型的类(*),最好的结果是运行时错误(考虑使用选择默认子句)

以上是关于Fortran 派生类型的主要内容,如果未能解决你的问题,请参考以下文章

确定内存中的 Fortran 派生类型大小

在 fortran 中命名派生类型的良好做法

Fortran 派生类型包含可从 C 访问的指针

Fortran 派生类型:

Fortran - 可分配派生类型的可分配数组

派生数据类型中的 Fortran、参数和静态表