我将一个可选掩码传递给子例程。在这个例程中,我有很多类似的陈述
...
if (present(Mask)) then
where(Mask)
y(:) = A(:)*B(:)
end where
else
y(:) = A(:)*B(:)
end if
...
这在代码重复方面非常难看。有什么建议可以更好地做到这一点吗?我的代码中有很多这样的语句,我需要对整个数组执行操作。
编辑: 至少一部分问题可以通过基本函数来解决。因为我在右侧有相同的操作我可以写
...
if (present(Mask)) then
where(Mask)
y(:) = multiply(A(:),B(:))
end where
else
y(:) = multiply(A(:),B(:))
end if
...
elemental real function multiply(a,b)
real, intent(in) :: a,b
multiply = a*b
end function
这样,我至少有一个单独的操作位置。
最佳答案
有一个选项(双关语)不使用可选参数,而是编写一个通用接口(interface)。例如,不要写
subroutine bar(arg0, opt)
integer, intent(inout) :: arg0
integer, intent(in), optional :: opt
arg0 = int(4 * atan(1.))
if (present(opt)) arg0 = arg0 + opt
module foo
你可以做到
interface bar
module procedure bar0
module procedure bar1
end interface bar
contains
subroutine bar0(arg0)
integer, intent(inout) :: arg0
arg0 = int(4 * atan(1.))
end subroutine bar0
subroutine bar1(arg0, opt)
integer, intent(inout) :: arg0
integer, intent(in) :: opt
arg0 = arg0 + opt
end subroutine bar1
end module foo
program bah
use foo
integer :: a0 = 1, a1 = 42
call bar(a0)
print *, a0
call bar(a0, a1)
print *, a0
end program bah
您可以从这种方法中获得的一个优势是 bar0
bar1 可以让编译器更好地进行优化
代码。 if (present(opt))
结构可能会妨碍。
关于fortran - 在子例程中传递和使用可选掩码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62742076/