Может ли производный тип от Fortran иметь компоненты из разных модулей? - PullRequest
0 голосов
/ 25 апреля 2018

Я занимаюсь разработкой производного типа.Он продолжает расти и делает модуль, в котором он находится, громоздким.Есть ли способ разбить модуль на несколько модулей и получить производный тип его компонентов из различных модулей?

Ответы [ 2 ]

0 голосов
/ 30 апреля 2018

Как указано в моем первом комментарии, в той части, на которую вы не ответили, вы можете использовать расширение типа, если вам действительно нужны компоненты как фактические компоненты производного типа, а не как компоненты другого производного типа, поэтомуесли вы хотите избежать дальнейшей структуризации типа как дерева.

Обратите внимание, что, как правило, не рекомендуется иметь большой плоский тип, но насколько я понимаю, это то, о чем вы просите, поэтомувот мой ответ ...

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
0 голосов
/ 29 апреля 2018

Как указывает @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
...