不使用“%”符号如何使用Fortran派生类型变量

3

我定义了一个名为 MATRIX 的类型和一个该类型的变量 A,如下所示:

TYPE MATRIX
    REAL, ALLOCATABLE, DIMENSION(:,:) :: MAT
END TYPE

TYPE(MATRIX) :: A

构造A并使用它的通常方式为:

ALLOCATE(A%MAT(2,2))

A%MAT(1,:) = [1,2]
A%MAT(2,:) = [3,4]

PRINT*, A%MAT

我想知道是否有可能在不写 A%MAT 的情况下使用变量 A 进行操作。换句话说,是否有任何方法将前面的代码块重写为以下形式(使用 A 而不是 A%MAT)。

ALLOCATE(A(2,2))

A(1,:) = [1,2]
A(2,:) = [3,4]

PRINT*, A

一种选择是使用参数化派生类型,这样您就不需要一个可分配的数组成员。另一个选择是将已经分配好的数组作为参数传递给构造函数。或者甚至可以使用自定义构造函数。 - Rodrigo Rodrigues
3
@RodrigoRodrigues,我认为这并不能解决%语法的需求。Masoud可能正在寻找一些定义好的操作(自定义添加、赋值、IO、索引等)。不幸的是,在Fortran中无法重载索引。 - Vladimir F Героям слава
1
你可以使用构造函数一次性设置整个数组,或者适当地重载赋值运算符。但是我认为,如果没有百分号,你无法指定单个元素或切片。 - Ian Bush
2
是的... print*, a 可以通过自定义派生类型 I/O来实现。对象初始化,你可以使用自定义构造函数得到类似于 a = matrix(2, 2) 的结果,或者使用参数化类型的 allocate(matrix(2, 2) :: a)。但是对于 a(1, :) = [1, 2],没有办法,它只能被解释为 a 是一个数组(或字符)。在 Fortran 中没有索引重载。 - Rodrigo Rodrigues
2个回答

2

您可以使用associate语句将某些表达式绑定到较短的名称。这可用于为变量的组成部分命名。

    allocate(A%mat(2, 2))
    associate(B => A%mat(:, :))
        B(1,:) = [1, 2]
        B(2,:) = [3, 4]
        write(*, *) B
    end associate

请注意,您还可以使用reshape和自动分配来消除一些切片。
! No allocate statement necessary.
A%mat = reshape([1, 2, 3, 4], [2, 2])

1
好的观点,但 B 只能在 associate 块中使用,而不能在整个程序体中使用。此外,我更喜欢不需要引入另一个辅助变量来处理 A 的解决方法。 - Masa
此外,我更喜欢一种不需要引入另一个辅助变量来处理A的解决方法。你可以使用 associate(A => A%mat)(覆盖派生类型的原始A)来实现。 - mcocdawc

2

很遗憾,目前Fortran标准(截至撰写本文时为Fortran 2018)不允许使用派生类型的a(1,:) = [1,2]语法。

一个提案希望在未来的Fortran标准中允许此语法。


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