interface - 使用具有显式接口的外部过程的类型绑定过程:有时它可以编译,有时不能
问题描述
我把之前的问题搞砸了,不得不删除它。这是一个新的:
我从这个非常有用的网站获得了大部分代码:
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 的一部分才能工作?
解决方案
在模块中,您已经为外部过程定义了一个接口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
细节留给有兴趣的读者从其他来源找到。
推荐阅读
- javascript - Puppeteer PDF 标题未显示在每一页上
- postgresql - postgres 12中带有前导零的隐蔽数字字符串到带有前导零的数值
- r - 警告:cat 中的错误:参数 1(类型 'list')不能由 R 闪亮 webtool 中的 'cat' [No stack trace available] 处理
- react-native - 图像未在 api 调用中显示
- c++ - c++指针使用向量类
- ruby-on-rails - 从 has many through 关联中查找匹配和不匹配记录的单次出现
- java - 文件夹的 Firebase 存储安全规则
- javascript - 单击 ImagePicker 时没有任何反应
- android - 如果安装是程序化的,则不会调用 MY_PACKAGE_REPLACED
- python - 对 Python 中的索引感到困惑