首页 > 解决方案 > 使用具有显式接口的外部过程的类型绑定过程:有时它可以编译,有时不能

问题描述

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

我从这个非常有用的网站获得了大部分代码:

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

如何编写子程序是我上面引用的链接没有说明的一件事。有没有办法做到这一点?或者initialiaze()必须是 shape_mod 的一部分才能工作?

标签: interfacefortranfortran90derived-types

解决方案


在模块中,您已经为外部过程定义了一个接口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定义的模块。这是一个简化。

最后,正如高性能标记所评论的那样,也许initialize甚至不必是一个绑定名称。相反,可以使用“构造函数”:

type mytype
end mytype

interface mytype
  procedure intialize_mytype
end interface

细节留给有兴趣的读者从其他来源找到。


推荐阅读