如何让Fortran函数优雅支持标量与向量输入?
实现支持标量与向量输入的Fortran通用函数
你的原代码存在语法错误:Fortran要求所有变量声明必须放在执行语句之前,不能在if代码块内声明变量,所以通过判断xlen来切换参数类型的写法是不合法的。
除了单独编写标量和向量版本的函数外,有两种更优雅的实现方式:
1. 泛型接口(推荐)
通过Fortran的泛型接口,可以将多个不同参数类型/维度的函数绑定到同一个名称,调用时编译器会自动根据输入参数匹配对应的函数实现,完全不需要修改调用代码。
修改后的完整代码如下:
program sinwave implicit none integer, parameter :: N = 100 real, dimension(N) :: x, t real :: x0, t0 integer :: i x = [((i-1)*0.12 + 1.0, i=1,N)] t = [((i-1)*0.05 + 0.2, i=1,N)] print *, test(x, t) x0 = x(N-14) t0 = t(N-14) print *, test(x0, t0) contains ! 泛型接口:将两个函数绑定到test名称 interface test module procedure test_scalar, test_array end interface test ! 标量输入版本 function test_scalar(x, t) result(y) implicit none real, intent(in) :: x, t real :: y y = sin(x + 0.1*t) end function test_scalar ! 数组输入版本 function test_array(x, t) result(y) implicit none real, intent(in) :: x(:), t(:) ! 假定形状数组,适配任意长度的一维数组 real :: y(size(x)) y = sin(x + 0.1*t) end function test_array end program sinwave
这种方式的优势是调用端完全透明,既可以传标量也可以传数组,编译器会自动处理匹配,代码可读性和维护性都很高。
2. 利用Fortran的数组隐式扩展
如果不想写两个函数,可以直接实现一个支持数组输入的函数,调用标量时将其包装为单元素数组。这种方式代码更简洁,但调用时需要手动包装标量:
program sinwave implicit none integer, parameter :: N = 100 real, dimension(N) :: x, t real :: x0, t0 integer :: i x = [((i-1)*0.12 + 1.0, i=1,N)] t = [((i-1)*0.05 + 0.2, i=1,N)] print *, test(x, t) x0 = x(N-14) t0 = t(N-14) print *, test([x0], [t0]) ! 将标量包装为单元素数组 contains function test(x, t) result(y) implicit none real, intent(in) :: x(:), t(:) real :: y(size(x)) y = sin(x + 0.1*t) end function test end program sinwave
这种方式省去了泛型接口的定义,但调用标量时需要额外的数组包装操作,适合简单场景。
内容的提问来源于stack exchange,提问作者Medulla Oblongata
相关产品推荐
相关产品推荐

