You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何移除Fortran扩展类型Namelist打印中的抽象类型前缀?

解决方案

gfortran 12.3.0在处理带继承关系的派生类型namelist输出时,默认会显式添加父类型的路径前缀,目前没有直接的编译选项可以关闭这一行为。你可以通过以下两种方式实现期望的输出格式:

方法一:手动格式化输出(推荐,实现简单)

直接绕过默认的namelist写入逻辑,手动按照目标格式输出参数:

program main
    use my_type
    implicit none

    type(the_settings) :: num
    namelist/nl_num/num

    open(unit=3,form='formatted',status='old',delim='apostrophe', file='example.nml')
    read(3,nl_num)
    close(3)

    ! 手动输出符合要求的namelist格式
    write(*,'(A)') '&NL_NUM'
    write(*,'(A,I0,A)') ' NUM%A=', num%a, '          ,'
    write(*,'(A,I0,A)') ' NUM%B=', num%b, '          ,'
    write(*,'(A,I0,A)') ' NUM%SPECIAL_CASE%A=', num%special_case%a, '          ,'
    write(*,'(A,I0,A)') ' NUM%SPECIAL_CASE%B=', num%special_case%b, '          ,'
    write(*,'(A)') ' /'
end program main

方法二:自定义类型格式化写过程(适合复杂类型场景)

为派生类型添加自定义的write(formatted)过程,控制组件的输出方式:

module my_type
    implicit none

    type, public, abstract :: settings
        integer :: a = 1
        integer :: b = 0
        contains
            procedure(settings_write), deferred :: write(formatted)
    end type settings

    abstract interface
        subroutine settings_write(this, unit, iotype, v_list, iostat, iomsg)
            import :: settings
            class(settings), intent(in) :: this
            integer, intent(in) :: unit
            character(*), intent(in) :: iotype
            integer, intent(in) :: v_list(:)
            integer, intent(out) :: iostat
            character(*), intent(inout) :: iomsg
        end subroutine settings_write
    end interface

    type, extends(settings), public :: settings_extended
        contains
            procedure :: write => settings_extended_write
    end type settings_extended

    type, extends(settings), public :: the_settings
        type(settings_extended) :: special_case
        contains
            procedure :: write => the_settings_write
    end type the_settings

contains

    subroutine settings_extended_write(this, unit, iotype, v_list, iostat, iomsg)
        class(settings_extended), 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,I0,A,I0,A)', iostat=iostat, iomsg=iomsg) &
            'A=', this%a, ', B=', this%b, ', '
    end subroutine settings_extended_write

    subroutine the_settings_write(this, unit, iotype, v_list, iostat, iomsg)
        class(the_settings), intent(in) :: this
        integer, intent(in) :: unit
        character(*), intent(in) :: iotype
        integer, intent(in) :: v_list(:)
        integer, intent(out) :: iostat
        character(*), intent(inout) :: iomsg
        integer :: ios

        write(unit, '(A)', iostat=ios, iomsg=iomsg) '&NL_NUM'
        if (ios /= 0) then
            iostat = ios
            return
        end if

        write(unit, '(A,I0,A)', iostat=ios, iomsg=iomsg) &
            ' NUM%A=', this%a, '          ,'
        if (ios /= 0) then
            iostat = ios
            return
        end if

        write(unit, '(A,I0,A)', iostat=ios, iomsg=iomsg) &
            ' NUM%B=', this%b, '          ,'
        if (ios /= 0) then
            iostat = ios
            return
        end if

        write(unit, '(A,I0,A)', iostat=ios, iomsg=iomsg) &
            ' NUM%SPECIAL_CASE%A=', this%special_case%a, '          ,'
        if (ios /= 0) then
            iostat = ios
            return
        end if

        write(unit, '(A,I0,A)', iostat=iostat, iomsg=iomsg) &
            ' NUM%SPECIAL_CASE%B=', this%special_case%b, '          ,'
        write(unit, '(A)') ' /'
    end subroutine the_settings_write

end module my_type

使用这个模块后,原主程序的write(*,nl_num)语句即可输出符合要求的格式。

内容的提问来源于stack exchange,提问作者narsonalin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 03:56:00