簡體   English   中英

如何使用名稱列表以派生類型編寫可分配數組?

[英]How to write an allocatable array in a derived type using namelists?

我在使用名稱列表編寫嵌套在派生類型中的可分配數組時遇到麻煩。 一個最小的例子如下所示。 我如何修改程序以使派生類型內部的可分配數組像未嵌套一樣工作?

program test

    implicit none

    type struct_foo
        integer, allocatable :: nested_bar(:)
    end type struct_foo

    integer, allocatable :: bar(:)
    type(struct_foo) :: foo
    ! namelist / list / foo, bar
    namelist / list / bar

    allocate(bar(5))
    bar = [1:5]

    allocate(foo%nested_bar(5))
    foo%nested_bar=[1:5]

    write(*,list)

end program test

將foo從名稱列表中注釋掉,它可以正常工作,並產生輸出:

 &LIST
 BAR     =           1,           2,           3,           4,           5
 /

包含foo時,程序無法編譯:

>> ifort -traceback test_1.f90 -o test && ./test
test_1.f90(20): error #5498: Allocatable or pointer derived-type fields require a user-defined I/O procedure.
    write(*,list)
--------^
compilation aborted for test_1.f90 (code 1)

如錯誤消息所述,您需要提供一個用戶定義的派生類型I / O(UDDTIO)過程。 對於具有可分配或指針組件的任何對象的輸入/輸出,這是必需的。

如何在文件中格式化派生類型的對象的格式完全在UDDTIO過程的控制之下。

下面是一個使用非常簡單的輸出格式的示例。 通常,實現名稱列表輸出的UDDTIO過程將使用與名稱列表輸出的其他方面一致的輸出格式,並且通常還將存在一個相應的UDDTIO過程,該過程隨后能夠讀回格式化的結果。

module foo_mod
  implicit none

  type struct_foo
    integer, allocatable :: nested_bar(:)
  contains
    procedure, private :: write_formatted
    generic :: write(formatted) => write_formatted
  end type struct_foo
contains
  subroutine write_formatted(dtv, unit, iotype, v_list, iostat, iomsg)
    class(struct_foo), intent(in) :: dtv
    integer, intent(in) :: unit
    character(*), intent(in) :: iotype
    integer, intent(in) :: v_list(:)
    integer, intent(out) :: iostat
    character(*), intent(inout) :: iomsg

    integer :: i

    if (allocated(dtv%nested_bar)) then
      write (unit, "(l1,i10,i10)", iostat=iostat, iomsg=iomsg)   &
          .true.,  &
          lbound(dtv%nested_bar, 1),  &
          ubound(dtv%nested_bar, 1)
      if (iostat /= 0) return
      do i = 1, size(dtv%nested_bar)
        write (unit, "(i10)", iostat=iostat, iomsg=iomsg)  &
            dtv%nested_bar(i)
        if (iostat /= 0) return
      end do
      write (unit, "(/)", iostat=iostat, iomsg=iomsg)
    else
      write (unit, "(l1,/)", iostat=iostat, iomsg=iomsg) .false.
    end if
  end subroutine write_formatted
end module foo_mod

program test
  use foo_mod

  implicit none

  integer, allocatable :: bar(:)
  type(struct_foo) :: foo
  namelist / list / foo, bar

  allocate(bar(5))
  bar = [1:5]

  allocate(foo%nested_bar(5))
  foo%nested_bar=[1:5]

  write (*,list)
end program test

UDDTIO的使用顯然需要實現此Fortran 2003語言功能的編譯器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM