首页 > 解决方案 > Fortran 派生类型可以包含来自不同模块的组件吗?

问题描述

我正在开发一种派生类型。它不断增长,并使得它所在的模块变得笨拙。有没有办法将模块分解为多个模块并让派生类型从各个模块中获取其组件?

标签: modulefortranderived-types

解决方案


正如@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

推荐阅读