作为派生数据类型的组件的命名常量

Posted

技术标签:

【中文标题】作为派生数据类型的组件的命名常量【英文标题】:Named constants as components of a derived data type 【发布时间】:2013-10-13 10:05:20 【问题描述】:

似乎 Fortran 90 不允许在派生数据类型中使用命名常量。这是真的? 以下代码不起作用。

program my_prog
implicit none
   type :: my_type
      integer, parameter :: a = 1
      real(kind(1.d0))   :: b
   end type my_type
   type (my_type) :: complex_type
end program my_prog

编译器说参数声明在派生类型定义中是不允许的。

当我删除 parameter 关键字时,一切正常。但是那我如何确保组件a 没有在其他地方修改呢?

【问题讨论】:

...我怎样才能确保a 没有在其他地方被修改? 你的意思是除了不使用它? :D 在 Fortran 2003 中还有许多其他的可能性。它可以是带有 setter/getter 方法的私有变量。它可以是一个受保护的组件... 【参考方案1】:

使常量(参数)成为主程序的局部实体而不是类型。如果您想更好地控制常量标识符的可见性和范围,请将常量放入模块中。

【讨论】:

谢谢。您正在提供解决我的问题的替代解决方案。您能否对派生数据类型中不允许的参数构造表示赞同或反对?需要确认它不是特定于编译器的。 这是语言规则的直接结果。它不是特定于编译器的。【参考方案2】:

根据标准,这是不允许的。 组件属性说明符对于 Fortran 90/95(第 4.4.1 节)只能是 pointerdimension,在 Fortran 2003(第 4.5.3 节)中还可以是 allocatable,此外codimensioncontiguousFortran 2008(第 4.5.4.1 节)。

你可以得到文件here。

我遇到了target 说明符的类似问题,这也是不允许的。

编辑: 为什么不试试private 组件?

module typedef
  type :: my_type
    integer, private :: a_int = 1
    real(kind(1.d0)) :: b
  contains
    procedure :: a
  end type my_type

contains
  function a(complex_type)
    class(my_type),intent(in) :: complex_type
    integer :: a
    a = complex_type%a_int
  end function
end module

program my_prog
  use typedef
  implicit none

  type (my_type) :: complex_type

  complex_type%b = 2.d0 ! This should work
  write(*,*) complex_type%a(), complex_type%b

!  complex_type%a_int = 3    ! This should fail

end program my_prog

【讨论】:

太棒了!私人是要走的路。只是一个澄清。在上面的代码中,'class(my_type), intent(in) :: complex_type' 应该改为'type(my_type), intent(in) :: complex_type'。至少在 Fortran 90 中! 从 Fortran 2003 开始​​,当且仅当定义的类型是可扩展的(my_type 是可扩展的)时,虚拟参数应该是多态的 (4.3.1.3)。所以在使用 Fortran 2003 及更高版本时,使用 type 而不是 class 会产生错误。【参考方案3】:

问题是:你为什么要这样做?

想象一下,您想创建一个包含 1000 个值的数组 my_type。结果将是,a 的值将被存储 1000 次。这浪费了将近 4kb 的内存(假设 int4)。更好的方法是在相应的模块中定义参数。

顺便说一句,在 Clerman 和 Spector 的 Modern Fortran 一书中,第 133 条规则规定,您应该在自己的模块中定义每个派生类型。对于这样的常数来说,这将是一个好地方。

【讨论】:

我不会有超过一份。我以您在 c 中使用 enumerate 的方式使用它。我有一个微分方程系统。而不是将向量称为“Y(0)、Y(1)”等。我想将它们称为“Y(var1)、Y(var2)”等。 'var1, var2' 等将是新类型数据类型中的常量参数。【参考方案4】:

您可以将其定义为私有并生成 get() 函数,但不能生成 set() 函数。 这样,您的数据将被很好地封装。

【讨论】:

以上是关于作为派生数据类型的组件的命名常量的主要内容,如果未能解决你的问题,请参考以下文章

枚举类型

求C语言代码

C++中的enum枚举

C++基础1(注释变量常量关键字标识符的命名规则数据类型)

C语言重点难点数据类型常量和变量

链技术go语言基础知识-数据类型变量和常量