使用具有显式接口的外部过程的类型绑定过程:有时编译,有时不编译

Type-bound procedure that uses an external procedure with an explicit interface: Sometimes it compiles, sometimes not

我搞砸了我之前的问题,不得不删除它。这是一个新的:

大部分代码来自 this quite helpful site:

module shape_mod

type shape
    integer :: color
    logical :: filled
    integer :: x
    integer :: y
contains
    procedure :: initialize
end type shape

type, extends(shape) :: rectangle
        integer :: length
        integer :: width
end type rectangle

type, extends(rectangle) :: square
end type square

interface
    subroutine initialize(sh, color, filled, x, y, length, width)
        import shape
        class(shape) :: sh
        integer :: color
        logical :: filled
        integer :: x
        integer :: y
        integer, optional :: length
        integer, optional :: width
  end subroutine
end interface

end module

subroutine initialize(sh, color, filled, x, y, length, width)

    ! initialize shape objects
    class(shape) :: sh
    integer :: color
    logical :: filled
    integer :: x
    integer :: y
    integer, optional :: length
    integer, optional :: width

    ! do stuff with shape

end subroutine initialize


program drv

use shape_mod

type(shape) :: sh

call sh%initialize(1, .true., 0, 0, 5, 10)

end program

编译失败(正如回答我之前问题的受访者所指出的那样)并出现错误:

gfortran shape2.f90
shape2.f90:38:16:

     class(shape) :: sh
                1
Error: Derived type ‘shape’ at (1) is being used before it is defined
shape2.f90:46:7: Error: Symbol ‘sh’ at (1) has no IMPLICIT type
shape2.f90:47:7: Error: Symbol ‘sh’ at (1) has no IMPLICIT type
shape2.f90:48:7: Error: Symbol ‘sh’ at (1) has no IMPLICIT type
shape2.f90:49:7: Error: Symbol ‘sh’ at (1) has no IMPLICIT type

所以,我的问题是,我怎样才能让 subroutine initialize() 了解 type shape?我唯一能想到的就是把use语句放在:

subroutine initialize(sh, color, filled, x, y, length, width)

    use shape_mod
    ! initialize shape objects
    class(shape) :: sh
    integer :: color
    logical :: filled
    ...
end subroutine initialize

但这给了我一个新的错误:

gfortran shape2.f90
shape2.f90:37:8:

     use shape_mod
        1
Error: ‘initialize’ of module ‘shape_mod’, imported at (1), is also the name of the current program unit

如何编写子例程是 link 我上面提到的一件事没有说明。有没有办法做到这一点?还是 initialiaze() 必须是 shape_mod 的一部分才能起作用?

在模块中,您已经为外部过程定义了一个接口 initialize。当您在子例程定义中使用此模块时,您可以访问子例程本身的接口。

你不能这样做。

幸运的是,您可以避免让

访问该界面
use shape_mod, only shape

现在,以上是必要的,因为在类型绑定中使用外部过程的设计。通常,人们不希望以这种方式使用外部过程。正如我们所见,使用外部过程会带来额外的复杂性,既要使用定义类型的模块,又要手动指定过程的接口。

有时外部接口会很有用,但这里导致问题的示例的目的可能是教学而不是简单。这里没有明显的理由说明为什么 initialize 不应该是一个模块过程。

相反,请考虑示例

interface
  subroutine ext()
  end subroutine
end interface

type mytype
 contains
  procedure(iface), nopass :: ext
end type

外部子例程 ext 没有传递对象虚拟对象(绑定有 nopass),因此不需要定义 mytype 的模块。这是一个简化。

最后,正如 High Performance Mark 评论的那样,也许 initialize 甚至不需要是绑定名称。相反,可以使用 "constructor":

type mytype
end mytype

interface mytype
  procedure intialize_mytype
end interface

详细信息留给感兴趣的 reader 从其他来源查找。