我试图在不同的派生类型之间添加转换函数。我'米 希望它们是返回其他派生类型的第一个派生类型的函数。只要它们在同一个文件和模块中,这就没问题了。但我真的希望它们能够被分成多个文件,否则它将是一个非常大的文件。由于依赖关系以及Fortran中缺少命名空间,我无法弄清楚如何执行此操作。
有办法做到这一点吗?
以下是我希望分成两个文件(每个派生类型一个)的示例。
Module ConversionStuff
implicit none
type A_T
real :: a, b, c
contains
procedure :: toX => a_toX
end type A_T
type X_T
real :: x, y, z
contains
procedure :: toA => x_toA
end type X_T
contains
function a_toX(this) result(x)
class(A_T), intent(inout) :: this
type(X_T) :: x
x%x = this%a * 2
x%y = this%b * 2
x%z = this%c * 2
end function a_toX
function x_toA(this) result(a)
class(X_T), intent(inout) :: this
type(A_T) :: a
a%a = this%x * 0.5
a%b = this%y * 0.5
a%c = this%z * 0.5
end function x_toA
End Module ConversionStuff
如果有拼写错误,我会道歉。我没有简单的方法在这台计算机上编译Fortran。
答案 0 :(得分:2)
在当前语言中,这很容易通过子模块处理 - 两种类型定义都与祖先模块一起进入“共享”单独模块过程的接口,然后在子模块之间拆分过程定义。
MODULE ConversionStuff
IMPLICIT NONE
TYPE :: A_T
REAL :: a, b, c
CONTAINS
PROCEDURE :: toX => a_toX
END TYPE A_T
TYPE :: X_T
REAL :: x, y, z
CONTAINS
PROCEDURE :: toA => x_toA
END TYPE x, y, z
INTERFACE
MODULE FUNCTION a_toX(this) RESULT(x)
IMPLICIT NONE
CLASS(A_T), INTENT(IN) :: this
TYPE(X_T) :: x
END FUNCTION a_toX
MODULE FUNCTION x_toA(this) RESULT(a)
IMPLICIT NONE
CLASS(X_T), INTENT(IN) :: this
TYPE(A_T) :: a
END FUNCTION x_toA
END INTERFACE
END MODULE ConversionStuff
SUBMODULE (ConversionStuff) Procedures_for_X
IMPLICIT NONE
CONTAINS
MODULE PROCEDURE a_toX
x%x = this%a * 2
x%y = this%b * 2
x%z = this%c * 2
END PROCEDURE a_toX
END SUBMODULE Procedures_for_X
...
在Fortran 2008之前,您有时可以使用另一种模拟上述方法的方法 - 程序的实现在一组单独编译的外部过程中使用该模块。需要注意外部程序无法看到自己的界面。
MODULE ConversionStuff
IMPLICIT NONE
TYPE :: A_T
REAL :: a, b, c
CONTAINS
PROCEDURE :: toX => a_toX
END TYPE A_T
TYPE :: X_T
REAL :: x, y, z
CONTAINS
PROCEDURE :: toA => x_toA
END TYPE x, y, z
INTERFACE
FUNCTION a_toX(this) RESULT(x)
IMPORT :: A_T
IMPORT :: X_T
IMPLICIT NONE
CLASS(A_T), INTENT(IN) :: this
TYPE(X_T) :: x
END FUNCTION a_toX
FUNCTION x_toA(this) RESULT(a)
IMPORT :: A_T
IMPORT :: X_T
IMPLICIT NONE
CLASS(X_T), INTENT(IN) :: this
TYPE(A_T) :: a
END FUNCTION x_toA
END INTERFACE
PRIVATE :: a_toX
PRIVATE :: x_toA
END MODULE ConversionStuff
FUNCTION A_toX(this) RESULT(x)
USE ConversionStuff
IMPLICIT NONE
CLASS(A_T), INTENT(IN) :: this
TYPE(X_T) :: x
...etc...
END FUNCTION A_toX
对于第二种方法,使用Fortran的可访问性属性(PUBLIC和PRIVATE)存在限制。
请注意,该问题与命名空间无关,因为通常会定义概念。
答案 1 :(得分:0)
在处理完其他事情后,差不多2个月后回到这里。我发现我觉得这个特定用法更加简单和优雅。我将离开之前接受的答案,因为它肯定会回答这个问题,但这是另一种方法。
它使用include关键字。直到现在我还没有理解它在编译包含文件之前没有编译包含文件。也许有些东西我不明白,但对于这种情况,我只想分成多个文件以便我的单个文件不是很大,我认为这种方法值得在我失去的东西中取舍因为它不是一个模块。如果我遗失了某些内容,请告诉我。
我的解决方案如下。
Module ConversionStuff
implicit none
type A_T
real :: a, b, c
contains
procedure :: toX => a_toX
end type A_T
type X_T
real :: x, y, z
contains
procedure :: toA => x_toA
end type X_T
contains
include "A.f90"
include "X.f90"
End Module ConversionStuff
A.f90
function a_toX(this) result(x)
class(A_T), intent(inout) :: this
type(X_T) :: x
x%x = this%a * 2
x%y = this%b * 2
x%z = this%c * 2
end function a_toX
X.f90
function x_toA(this) result(a)
class(X_T), intent(inout) :: this
type(A_T) :: a
a%a = this%x * 0.5
a%b = this%y * 0.5
a%c = this%z * 0.5
end function x_toA