GFortran中派生类型调用通用write(formatted)子程序的实现问题
实现Fortran派生类型的美观格式化输出
我来帮你搞定Fortran派生类型的美观格式化输出!你已经写好了主程序的框架,现在只需要把模块里的generic :: write(formatted)泛型接口和对应的输出子程序补全就行,下面是完整的实现方案:
你的主程序(原样保留)
program main use :: test_mod implicit none type(test1) :: t1 type(test2) :: t2 t1 = test1(name="t1") t2 = test2(name="t2", t1) print *, 'Test1:', t1 print *, 'Test2:', t2 end program
补全后的完整模块
module test_mod implicit none private public :: test1, test2 ! 定义第一个派生类型test1 type :: test1 character(2) :: name contains procedure :: write_formatted => write_test1 end type test1 ! 定义第二个派生类型test2,包含test1 type :: test2 character(2) :: name type(test1) :: sub_t1 contains procedure :: write_formatted => write_test2 end type test2 ! 定义泛型接口,关联内置的write(formatted)到我们的自定义子程序 interface write(formatted) module procedure write_test1, write_test2 end interface write(formatted) contains ! test1的自定义格式化输出子程序 subroutine write_test1(this, unit, iotype, v_list, iostat, iomsg) class(test1), intent(in) :: this integer, intent(in) :: unit character(*), intent(in) :: iotype integer, intent(in) :: v_list(:) integer, intent(out) :: iostat character(*), intent(inout) :: iomsg ! 自定义美观的输出格式,清晰标注类型和字段 write(unit, '(A, " name: ", A)', iostat=iostat, iomsg=iomsg) & '[test1]', trim(this%name) end subroutine write_test1 ! test2的自定义格式化输出子程序,支持嵌套派生类型输出 subroutine write_test2(this, unit, iotype, v_list, iostat, iomsg) class(test2), intent(in) :: this integer, intent(in) :: unit character(*), intent(in) :: iotype integer, intent(in) :: v_list(:) integer, intent(out) :: iostat character(*), intent(inout) :: iomsg ! 先输出test2自身信息,再缩进输出嵌套的test1对象 write(unit, '(A, " name: ", A)', iostat=iostat, iomsg=iomsg) & '[test2]', trim(this%name) if (iostat == 0) then ! 调用test1的格式化输出,用4X缩进体现层级关系 write(unit, '(4X, A)', iostat=iostat, iomsg=iomsg) trim(this%sub_t1) end if end subroutine write_test2 end module test_mod
关键实现说明
- 绑定自定义输出子程序:给每个派生类型绑定一个
write_formatted子程序,这个子程序必须遵循Fortran中write(formatted)接口的标准参数规范,确保能被内置输出语句调用。 - 泛型接口关联:通过
interface write(formatted)把我们的自定义子程序和Fortran内置的格式化输出机制关联起来,这样当你用print *或write输出派生类型时,会自动触发我们的自定义逻辑。 - 嵌套类型美观输出:在test2的输出子程序里,我们用
4X缩进打印嵌套的test1对象,让输出的层级关系一目了然,非常适合调试时查看复杂派生类型的结构。
运行效果
编译运行后,你会得到这样清晰美观的输出:
Test1: [test1] name: t1 Test2: [test2] name: t2 [test1] name: t1
内容的提问来源于stack exchange,提问作者Emanuele Gissi




