为什么Fortran会在表达式中将标量表达式提升为数组,而不是将其作为过程的参数?特别是,标准机构为什么要做出这个设计决定?是否仅仅是因为含糊不清,程序是否应该过载?在这种情况下,错误消息会是一种替代方法吗?
例如,在下面的代码中,最后一条语句x = foo(7)
会产生GFortran错误:Error: Rank mismatch in argument 'a' at (1) (1 and 0)
。
module m
public :: foo
contains
function foo(a) result(b)
integer, dimension(:) :: a
integer, dimension(size(a)) :: b
b = a+1
end function foo
end module m
program p
use m
integer, dimension(4) :: x
integer, parameter, dimension(4) :: y = (/1,2,3,4/)
x = 7
x = foo(x)
x = foo(y)
x = foo(x + 7)
x = foo(7)
end program p
这个问题应该问为什么数组赋值会将标量值源提升为数组目标;与数组函数不同。不过,我认为这只是一个方便的特例。感谢您在下面的乞求帽中收到的任何评论。
如果您希望函数处理scaler和数组参数,请将其声明为"elemental"并带有scaler伪参数。然后,它将能够处理缩放器和数组的实际参数,包括缩放器表达式。那能满足你的需要吗?
变化:
elemental function foo(a) result(b)
integer, intent (in) :: a
integer :: b
b = a+1
end function foo
也许他们提供了一种做你想做的事的方法,一种方法就足够了?
使用显式接口(使用模块过程时会自动获得(在Fortran中调用过程需要TKR(类型、种类、秩(匹配。由于数组与标量的类型不同,更不用说秩不匹配了,所以这是不允许的。
是否因为模糊性而应该重载程序
这将是一个问题,是的。
在这种情况下,错误消息会是一种替代方法吗
粉红色的独角兽会存在吗?也许吧,但据我所知,他们没有。IOW,Fortran标准目前要求TKR匹配,因此符合标准的编译器必须强制执行这一要求。如果你想改变这一点,我建议你向标准委员会提出建议。
我认为这个问题的答案非常清楚。让我们稍微修改一下您的示例:
module m
public :: foo
contains
function foo(a) result(b)
integer, dimension(:) :: a
integer, dimension(size(a)) :: b
b = a+1
a(2) = -777 ! new line; modify one element
end function foo
end module m
program p
use m
integer :: x
integer, dimension(4) :: y
x = 7
y = foo(x) ! pass a scalar
end program p
在调用foo之后,x应该是什么?
现在,当然,根据它是否是intent(in)
变量,您可以拥有参数传递更改的语义,但这是而不是,这将为程序员澄清。
如果函数调用应该以某种方式在数组元素上"分布",那么正如MSB所指出的,elemental就是最好的方法。否则,只需要确保自己的参数与自己的参数相匹配。