6

似乎 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没有在其他地方修改呢?

4

4 回答 4

5

根据标准,这是不允许的。对于Fortran 90/95(第 4.4.1 节)、Fortran 2003(第 4.5.3 节)和Fortran 2008(第 4.5.4.1节),组件属性说明符只能是pointer和。dimensionallocatablecodimensioncontiguous

你可以在这里得到文件。

我遇到了与说明符类似的问题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
于 2013-10-07T09:27:12.357 回答
5

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

于 2013-10-06T23:24:19.120 回答
3

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

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

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

于 2013-10-07T12:01:20.693 回答
1

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

于 2014-07-01T20:25:55.243 回答