Я думаю об использовании функции субмодулей в Фортране и настроил небольшой тестовый пример.У меня есть два вопроса, связанных с их использованием.Ниже приведен пример кода:
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
Хотя я понимаю, что это может привести к некоторому вводящему в заблуждение и сложному для понимания коду.
(я использую gfortran 8.3.0на OS X)