创建一个取决于其元素之一的用户定义类型

时间:2019-02-27 19:23:36

标签: types fortran user-defined-functions

我试图定义一个用户定义的类型,该类型的元素之一取决于另一个。这是一个测试代码,总结了我的尝试方式;

module def
  type vector
    integer, parameter :: long
    real,dimension(1:long) :: vec
  end type vector
end module def

program main
  use def
  implicit none

  type(vector) :: y
  y%long = 2
  y%vec = (/1.0d0, 2.0d0/)

  print*, y

end program main

但是似乎无法以这种方式完成,因为当我在gfortran中进行编译时,出现以下错误:

integer, parameter :: long
                  1
Error: Attribute at (1) is not allowed in a TYPE definition
testmodule.f03:4:17:

这应该怎么做?

1 个答案:

答案 0 :(得分:3)

  

这应该怎么做?

实际上,对这个问题有一个很直接的回答:参数化派生类型

@HighPerformanceMark的说法是正确的,尽管今天(2019年)已在16年前的标准中提供了此功能,但编译器几乎没有涵盖它。

尽管事实上,这是尽管有一些有关此问题的问题,但我还是决定写此答案的原因,但我想抛开围绕此功能的争议,并提出一个尖锐的最终建议:使用它 strong>。

当今有at least 5个主要的编译器(Cray,GNU,IBM,Intel,PGI)实现了此功能。他们中的大多数人仍然存在错误,但需要以进行使用和测试。然后,如果/如果发现错误,请向供应商报告。只有这样,此功能才能打破在其上创建的 stigma 并变得流行。

我知道我们每个人都有认真的工作要做,没有时间花在“花哨的新未经测试的东西”上,并且需要经过验证的,有效的,数学上合理的解决方案。毕竟,这就是为什么我们选择Fortran。几年前,我不会为这个人推荐它,但是现在大多数实现都达到了值得下注的可用性水平,并且使用是修整粗糙边缘的唯一方法。

参数化派生类型可以直观地转换您所描述的实际问题。它提供了一种自动(优雅)的方法来对类型的域进行建模,同时考虑了数学和编程方面。您的程序的正确语法是:

module def
  type vector(long)
    integer, len :: long
    real, dimension(long) :: vec
  end type vector
end module def

program main
  use def
  implicit none

  type(vector(2)) :: y
  y%vec = [1.0, 2.0]

  print*, y

end program main

您可以在网上here或您最喜欢的现代Fortran 书中找到有关此信息的更多信息。