为什么关键字“end”可以传递到 MATLAB 中的函数句柄而不引发错误?

问题描述 投票:0回答:1

考虑最小可重复的示例:

f = @(x) x
f(end)

请注意,MATLAB 语法突出显示实际上并没有以蓝色突出显示 end,这表明它没有解析为关键字,即使 Stack Overflow 语法突出显示也是如此。

输出:

f =

  function_handle with value:

    @(x)x


ans =

     1

你甚至可以做类似的事情

f = @(x) x
a = f(end + 1)
b = f(end - 100)
c = f(2 + end)

输出:

a =

     2


b =

   -99


c =

     3

常规功能

如果你有常规功能,这不起作用

foo(end)

function x = foo(x)
end
Error: <filename> Line: 1 Column: 5
The end operator must be used within an array index expression.

假设

由此看来,end 被强制转换为值 1,类似于布尔/逻辑 true 被强制转换为 1 的方式。我的假设是,由于函数句柄实际上是函数句柄的 1x1 数组,因此 end 关键字是替换为数组的最后一个有效索引 1。由于函数不存储为数组,因此它不适用于实际函数。

我的bug

我有一个特别讨厌的错误,我试图索引到一个与函数句柄名称相似的数组中:

x = 1:5
foo = @(x) x
foos = foo(x) % [1, 2, 3, 4, 5]
out = foos(1) + 2 * sum(foos(2:end-1)) + foo(end)
% Expected: out = 1 + 2 * (2 + 3 + 4) + 5 = 24, Got: out = 1 + 2 * (2 + 3 + 4) + 1 = 20

显然,我重命名了变量以使它们更容易区分。尽管如此,这种行为似乎对我能想到的任何事情都没有用。这是每个对象(包括函数句柄)秘密作为数组的结果的产物吗?如果是这样,用户是否可以采取任何措施来防止这种情况发生,或者是否需要 MathWorks 进行修复?

matlab keyword coercion type-coercion undocumented-behavior
1个回答
0
投票

不存在“秘密数组”——MATLAB 中的每个值都是一个数组。 MATLAB 对数组索引使用与函数求值相同的语法,因此存在歧义。该行为记录如下:https://uk.mathworks.com/help/matlab/matlab_oop/overload-end.html

基本上,当 MATLAB 在索引表达式中遇到

end
时,它会调用被索引对象的
end
方法来计算出适当维度中的最后一个元素。您可以为您编写的类实现您自己的
end
方法 - 仅当您编写的类是具有数组类型行为的标量实例时才有用。

奇怪的事情发生是因为“索引”到

function_handle
实际上是对函数求值。但是,在解释该“索引”表达式的参数时,适用有关计算
end
方法的常用规则,并且由于
function_handle
数组只能是标量,因此它始终返回值 1。

© www.soinside.com 2019 - 2024. All rights reserved.