我正在开发派生类型。它不断增长,正在使它所处的模块变得笨拙。有没有办法将模块分解为多个模块,并使派生类型从各个模块中获取其组件?
答案 0 :(得分:3)
正如@francescalus所指出的,您可以使用其他模块中的派生类型 创建新的派生类型。我认为他的例子有点短,所以我写了一篇 我希望这个小例子会让你知道这样的事情 可以工作。也许这个例子比严格必要的更长,但我是 享受自己。
我的派生类型描述了旅行计划,包括行李和行程。 它附带一个子程序,可以打印一个给定的旅行计划。
module travel
use Luggage
use Routing
type tTravel
type(tItinerary) :: trip
type(tSuitcase) :: suitcase
end type tTravel
contains
subroutine printTravel(travel)
implicit none
type(tTravel), intent(in) :: travel
print '(a)',' Luggage:'
call printSuitcase(travel%suitcase)
print '(a)',' Itinerary:'
call printItinerary(travel%trip)
end subroutine printTravel
end module travel
旅行计划的两个组成部分,行李和行程,每个都有自己的 模块。首先,行李模块:
module Luggage
type tSuitcase
integer :: socks = 2
integer :: shirts = 1
integer :: underwear = 1
integer :: raincoats = 0
end type tSuitcase
contains
subroutine printSuitcase(suitcase)
implicit none
type(tSuitcase), intent(in) :: suitcase
print '(i10,a)', suitcase%socks,' socks'
print '(i10,a)', suitcase%shirts,' shirts'
print '(i10,a)', suitcase%underwear,' underwear'
print '(i10,a)', suitcase%raincoats,' raincoats'
end subroutine printSuitcase
end module Luggage
接下来,行程模块:
module Routing
integer, parameter :: &
HOME=1, MONACO=2, IBIZA=3, BIARRITZ=4, &
nDESTINATIONS=4
character(len=8), parameter :: destination_names(nDESTINATIONS) = (/ &
'Home ', 'Monaco ', 'Ibiza ', 'Biarritz' /)
integer, parameter :: maxTripLen = 100
type tItinerary
integer :: length = 0
integer :: destinations(maxTripLen)
end type tItinerary
contains
subroutine addDestination(trip,destination)
implicit none
type(tItinerary), intent(inout) :: trip
integer, intent(in) :: destination
if (destination<1 .or. destination>nDESTINATIONS) &
stop('illegal destination')
if (trip%length >= maxTripLen) stop('Trip too long')
trip%length = trip%length + 1
trip%destinations(trip%length) = destination
end subroutine AddDestination
subroutine printItinerary(trip)
implicit none
type(tItinerary), intent(in) :: trip
integer :: i
if (trip%length==0) then
print '(a)',' Empty itinerary'
else
print '(100(a))',' '//trim(destination_names(trip%destinations(1))), &
('-',trim(destination_names(trip%destinations(i))), i=2,trip%length)
end if
end subroutine printItinerary
end module Routing
现在我需要的只是一个主程序:
program nestedModule
use travel
implicit none
type(tTravel) :: plans
print '(a)','Before planning anything:'
call printTravel(plans)
print *
print '(a)','Planning a trip ... hold on'
print *
call addDestination(plans%trip,HOME)
call addDestination(plans%trip,IBIZA)
call addDestination(plans%trip,BIARRITZ)
call addDestination(plans%trip,HOME)
print '(a)','Now my plans are:'
Call printTravel(plans)
end program nestedModule
答案 1 :(得分:2)
正如我在第一篇评论中指出的那样,在你没有回复的部分中,如果你确实需要组件作为派生类型的实际组件,而不是另一个派生类型的组件,则可以使用类型扩展,所以如果你想避免进一步将类型结构化为树。
请注意,一般来说,拥有大型扁平型不是一个好主意,但据我所知它是你要求的,所以这里是我的答案......
module mod1
type part1
...many components
end type
end module
module mod2
use mod1
type, extends(part1) :: part2
...many other components
end type
end module
module the_actual_type_mod
use mod2
type, extends(part2) :: the_actual_type
...many other components
end type
end module
提到的另一种方式是include
。结果不等同,但为了您的目的几乎相同
module the_actual_type_mod
use mod2
type the_type
include "part1.f90"
include "part2.f90"
include "part3.f90"
end type
end module