Fortran衍生类型赋值

15

假设我有一个基于Fortran的派生类型

type :: atype
    integer :: n
    integer :: a(10)
    integer, allocatable :: b(:)
 end type

我有两个这种类型的实例

type(atype) :: t1, t2

当我执行下面的赋值语句时,实际上会发生什么?

t2 = t1

我对此感兴趣,因为我想要正确地复制派生类型变量。这意味着标量分量应相等,数组分量的每个元素应相等,并且可分配数组应具有相同的分配大小和元素应相等。目前,我只会编写一个子程序,以正确地复制和分配这些分量。

subroutine copy_atype(from, to)
    type(atype) :: from, to
    to%n = from%n
    to%a = from%a
    if (allocated(to%b)) deallocate(to%b)
    if (allocated(from%b) then
        allocate(to%b(size(from%b)))
        to%b = from%b
    end if
end subroutine

我希望您能告诉我如何找到标准中适当的部分。

我正在使用gfortran 4.7。

2个回答

16
在没有适当的定义赋值程序可以用于将一个atype分配给另一个时,会发生内在派生类型赋值。这在F2008 7.2.1.3中有描述。对于您的类型定义,内在派生类型赋值基本上会执行您的过程所做的操作:
- 非可分配组件(它们本身没有类型绑定定义的赋值)使用内在赋值进行赋值。如果它们有类型绑定赋值,则会使用它。 - 被分配对象中的可分配组件如果已经被分配,则会被解除分配,并使用相同的类型、类型参数和边界重新分配,然后使用类型绑定定义的赋值(如果适用)或内在赋值来传输值。 - 指针组件是指针赋值; - 协作组件必须在变量和表达式之间匹配分配状态,并使用内在赋值进行传输。

2
在原始示例“t2=t1”中,假设未分配“t1%b”,而已分配“t2%b”。当您执行“t2=t1”时,“t1%b”会被释放吗?对于这种情况,答案有点不清楚。 - Alex
1
我认为你混淆了t1和t2。请看第二个圆点的第一部分——右侧值中组件的释放操作不受其分配状态的限制。组件的重新分配必须是有条件的。 - IanH
我对Fortran中指针的实现和使用不熟悉,但在C/C++中很熟悉。在这个上下文中,"pointer assigned"是什么意思? - jvriesem
1
@jvriesem 在Fortran中指针分配的操作是 lhs_pointer => rhs_target. - IanH

3
这与几天前提出的一个问题非常相似:Nested derived type with overloaded assignment。查看那里接受的答案以获得详细解释。
您可以直接使用子例程copy_atype来形成赋值运算符:
type :: atype
    integer :: n
    integer :: a(10)
    integer, allocatable :: b(:)
contains
    procedure :: copy_atype
    generic :: assignment(=) => copy_atype
end type

这样,您可以直接将相同类型的值分配给类型为atype的变量。您甚至可以通过给出适当子例程的逗号分隔列表来将赋值扩展到其他类型的变量。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接