我正在考虑在Fortran中使用子模块功能,并设置了一个小的测试示例。我有两个与其用法有关的问题。以下是示例代码:
module points
type :: point
real :: x, y
end type point
interface
module function point_dist(a, b) result(distance)
type(point), intent(in) :: a, b
real :: distance
end function point_dist
end interface
end module points
submodule (points) points_a
contains
module procedure point_dist
distance = sqrt((a%x - b%x)**2 + (a%y - b%y)**2)
end procedure point_dist
end submodule points_a
这有效,在我的程序中,我可以这样使用它:
program test
use points
real(kind(1.0D0)) :: result
type (point) :: p1, p2
p1%x = 1
p1%y = 1
p2%x = 2
p2%y = 2
result = point_dist(p1, p2)
write(*,*) result
end program test
1)但是我想知道是否有可能有两个使用相同接口但提供不同结果的子模块。这有一些用途,我们有不同的公式来计算相同的物理量。下面是我想象它会如何工作,即使它没有。
module points
type :: point
real :: x, y
end type point
interface
module function point_dist(a, b) result(distance)
type(point), intent(in) :: a, b
real :: distance
end function point_dist
end interface
end module points
submodule (points) points_a
contains
module procedure point_dist
distance = sqrt((a%x - b%x)**2 + (a%y - b%y)**2)
end procedure point_dist
end submodule points_a
submodule (points) points_b
contains
module procedure point_dist
distance = 2.0*sqrt((a%x - b%x)**2 + (a%y - b%y)**2)
end procedure point_dist
end submodule points_b
我在程序中遇到错误,因为我只有语句use points
,它抱怨point_dist
的重复定义。是否可以指定我想使用哪个子模块?
2)我也看了但是无法找出是否可以在同一个子模块中为不同的程序使用相同的模块级接口。在我的脑海中它将是这样的:
module points
type :: point
real :: x, y
end type point
interface
module function point_dist(a, b) result(distance)
type(point), intent(in) :: a, b
real :: distance
end function point_dist
end interface
end module points
submodule (points) points_a
contains
module procedure (type=point_dist) point_dist_a
distance = sqrt((a%x - b%x)**2 + (a%y - b%y)**2)
end procedure point_dist_a
module procedure (type=point_dist) point_dist_b
distance = 2.0*sqrt((a%x - b%x)**2 + (a%y - b%y)**2)
end procedure point_dist_b
end submodule points_a
虽然我意识到这可能导致一些非常误导和难以遵循的代码。
(我在OS X上使用gfortran 8.3.0)
1)但是我想知道是否有可能有两个使用相同接口但提供不同结果的子模块。这有一些用途,我们有不同的公式来计算相同的物理量。
如果这是可能的,你是如何计划使用它的?我的意思是,如果你有两个不同的实现可用于功能point_dist
thay可能产生不同的结果,你不会想要它们不匹配,是吗?
如果您希望它们具有相同的名称,您(和编译器)必须能够识别您正在呼叫的那个。这通常通过函数重载完成。在Fortran,你可能有一个generic interface
。但是发送的功能必须在它们的界面(参数类型和/或数量,位置以及其他规则)之间有所不同。你知道吗,其他人怎么会知道你指的是哪两个?
2)我也看了但是无法找出是否可以在同一个子模块中为不同的程序使用相同的模块级接口。
正如我所说,一个接口确实可以封装多个过程,如果它们是可区分的。
module points
type :: point
real :: x, y
end type point
interface point_dist
module function point_dist_a(a, b) result(distance)
type(point), intent(in) :: a, b
real :: distance
end function
module function point_dist_b(a, b, k) result(distance)
type(point), intent(in) :: a, b
real, intent(in) :: k
real :: distance
end function
end interface
end module points
submodule (points) points_a
contains
module procedure point_dist_a
distance = sqrt((a%x - b%x)**2 + (a%y - b%y)**2)
end procedure point_dist_a
end submodule points_a
submodule (points) points_b
contains
module procedure point_dist_b
distance = k*sqrt((a%x - b%x)**2 + (a%y - b%y)**2)
end procedure point_dist_b
end submodule points_b
测试:
program test
use points
real(kind(1.0D0)) :: result
type (point) :: p1, p2
p1%x = 1
p1%y = 1
p2%x = 2
p2%y = 2
result = point_dist(p1, p2)
write(*,*) result
result = point_dist(p1, p2, 2.0)
write(*,*) result
end program test
作为结束语,submodules
与这一切完全无关。