作为派生数据类型的组件的命名常量
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 节)只能是 pointer
和 dimension
,在 Fortran 2003(第 4.5.3 节)中还可以是 allocatable
,此外codimension
和 contiguous
Fortran 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() 函数。 这样,您的数据将被很好地封装。
【讨论】:
以上是关于作为派生数据类型的组件的命名常量的主要内容,如果未能解决你的问题,请参考以下文章