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

Fortran模块如何覆盖其他模块的子程序?现有尝试未生效求方案

Fortran模块中子程序调用的动态替换问题

顺带一提,此问题不涉及派生类型中的函数。

我希望实现如下功能:现有module test1,代码如下:

cat test_mod_1.F90

module test1

        contains

                subroutine sub1()
                       ! do interesting stuff that any inheriting module
                       ! will want to do ....
                       ! then do something specific to this module:
                        call sub2()
                end subroutine sub1

                subroutine sub2()
                        print *, "I am test1"
                end subroutine sub2

end module test1

test1被module test2引用:

cat test_mod_2.F90

module test2

        use test1, test1_sub2 => sub2

        contains

                subroutine sub2()
                        print *,"I am test2"
                end subroutine sub2

end module test2

(顺带一提,若无上述重命名语句,test2无法编译。)

随后我编写了主程序testmain,它仅使用test2而非test1:

cat testmain.F90

program testmain
        use test2
        call sub1()
end program

我期望输出信息"I am test2",但实际结果不符:

> gfortran -o tester test_mod_1.F90 test_mod_2.F90 testmain.F90
> ./tester
 I am test1

请问是否有办法让主程序调用test2中的sub2()而非test1中的?


解决方案

原代码无法实现预期效果的核心原因是:Fortran的模块子程序调用是静态绑定的。test1模块内的sub1调用的是自身模块定义的sub2,不会因为其他模块导入后定义同名子程序而改变绑定关系。

要实现动态替换调用目标,可使用过程指针来实现动态绑定,修改后的代码如下:

修改后的test1模块

cat test_mod_1.F90

module test1
  implicit none
  ! 定义sub2的抽象接口,规范子程序签名
  abstract interface
    subroutine sub2_interface()
    end subroutine sub2_interface
  end interface
  ! 声明过程指针,指向符合上述接口的子程序
  procedure(sub2_interface), pointer :: sub2 => null()

contains

  subroutine sub1()
    ! 执行通用逻辑后,调用当前绑定的sub2
    ! do interesting stuff that any inheriting module will want to do ....
    call sub2()
  end subroutine sub1

  ! test1默认的sub2实现
  subroutine test1_sub2()
    print *, "I am test1"
  end subroutine test1_sub2

end module test1

修改后的test2模块

cat test_mod_2.F90

module test2
  use test1
  implicit none

contains

  ! test2自定义的sub2实现
  subroutine test2_sub2()
    print *, "I am test2"
  end subroutine test2_sub2

  ! 初始化函数:将test1的sub2指针指向test2的实现
  subroutine init_test2()
    sub2 => test2_sub2
  end subroutine init_test2

end module test2

修改后的主程序

cat testmain.F90

program testmain
  use test2
  implicit none
  ! 先初始化test2,完成过程指针的绑定替换
  call init_test2()
  call sub1()
end program

编译运行结果

> gfortran -o tester test_mod_1.F90 test_mod_2.F90 testmain.F90
> ./tester
 I am test2

内容的提问来源于stack exchange,提问作者bob.sacamento

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 11:42:51