Matlab中'end'的语义是什么?

时间:2014-04-11 15:22:23

标签: matlab indexing

通常使用end关键字作为在Matlab中访问或扩展数组的快捷方式,如

>> x = [1,2,3];
>> x(1:end-1)
ans =
    1   2
>> x(end+1) = 4
x =
    1   2   3   4

然而,我惊讶地发现以下内容也有效

>> x(1:min(5, end))
ans =
    1   2   3   4

我认为end可能是一种特殊形式,如:,可以在索引操作中使用特殊形式,因此我创建了一个类来检测此

classdef IndexDisplayer
  methods
    function subsref(self, s)
      disp(s);
    end
  end
end

您可以在以下示例

中查看:的特殊情况
>> a = IndexDisplayer;
>> a(1:3)
    type: '()'
    subs: {[1 2 3]}
>> a(:)
    type: '()'
    subs: {':'}

然而,当我用end索引时,我只看到

>> a(end)
    type: '()'
    subs: {[1]}

此处end已替换为11来自哪里?我的第一个猜测是,索引表达式end中的任何x(end)都会被调用length(x)所取代,所以我尝试覆盖length

classdef IndexDisplayer
  methods
    function subsref(self, s)
      disp(s);
    end
    function len = length(self)
      len = 10;
    end
  end
end

然而,这给出了

>> a = IndexDisplayer;
>> length(a)
ans =
    10
>> a(end)
    type: '()'
    subs: {[1]}

这样理论就不在窗外了。任何人都可以解释end的语义吗?

2 个答案:

答案 0 :(得分:17)

首先,我认为你的语法x(1:min(5, end))是有效的,或者至少是一个意想不到的功能。当我在MathWorks时,我记得有人指出这一点,并且相当多的开发人员不得不花费一些时间来弄清楚发生了什么。我不确定他们是否真的同意这是否是一个问题。

解释end的(预期)语义:end实现为函数ind = end(obj, k, n)k是包含end的表达式的索引,n是表达式中索引的总数。

因此,例如,当您致电a(1,end,1)时,k为2,因为end位于参数2中,n为3,因为有3个参数

ind作为可以替换表达式中的end的索引返回。

您可以为自己的课程重载end(与您可以重载colonsizesubsref等相同的方式。

扩展你的例子:

classdef IndexDisplayer
  methods
    function ind = end(self,k,n)
        disp(k)
        disp(n)
        ind = builtin('end', self, k, n);
    end
  end
end

>> a = IndexDisplayer;
>> a(1,end,1)
 2
 3

有关详细信息,请参阅here

答案 1 :(得分:4)

我发现这也是一种好奇心。不过,我经常使用(利用?)这种行为来缩短语句。例如,在this answer中,为了获得向量的k个元素以外的所有元素,我发现了一个干净的解决方案,

vector(setdiff(1:end,k))

end取代了对numel(vector)的通话。对于标量k,这是vector(1:end ~= k)vector([1:k-1 k+1:end])的替代方案。当时看起来非常合理,虽然我提请注意这种用法的奇怪之处。这真是不好的做法吗?或许,但我已经接受了它的价值并继续前进。

我没有提供任何有关其工作原理或规则的见解,正如Sam Roberts在答案中所做的那样,但从概念上讲,我认为这是一个背景问题。也就是说,当end发生时,我会假设它评估为具有最直接范围的数组的索引(或维度下标),查看" up"通过嵌套语句来做出决定。不确定这是否是正确的措辞,但它似乎是解释end的操作的有用方法。

我还没有被这种解释所困扰。