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

时间:2018-07-16 16:52:14

标签: interface fortran fortran90 derived-types

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

我从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

如何编写子例程是我上面引用的链接所不具备的一件事。有没有办法做到这一点?还是initialiaze()必须是shape_mod的一部分才能起作用?

1 个答案:

答案 0 :(得分:2)

在模块中,您为外部过程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

留下详细信息供感兴趣的读者从其他来源中查找。