【问题标题】:Usage of empty array allocation for custom class自定义类的空数组分配的使用
【发布时间】:2015-04-06 04:04:24
【问题描述】:

说,我们有一个班级Car

classdef Car < handle
    properties
        wheels = 4;
    end
    methods
        function obj = Car()
        end
    end
end

我们可以像这样制造十辆汽车

cars = Car.empty();

for ii = 1:10
    cars(end+1) = Car;
end

但是,可以先制作一个空的汽车数组

>> cars = Car.empty(0,10)

cars = 

  0x10 Car array with properties:

    wheels

我不明白的是:如果现在将一辆汽车放入其中,则数组似乎缩小为单个元素

>> cars(1) = Car

cars = 

  Car with properties:

    wheels: 4

那么,分配这样一个空数组有意义吗?有哪些用例?

【问题讨论】:

    标签: arrays matlab oop allocation


    【解决方案1】:

    首先,请注意,您的问题与自定义类没有直接关系 - 您可以使用任何 MATLAB 变量类型来执行此操作。例如,

    >> a = double.empty(0,10)
    a =
       Empty matrix: 0-by-10
    

    所以你的问题是

    我不明白的是:如果现在将一辆汽车放入其中,则数组似乎缩小为单个元素

    不,它已增长为单个元素。我想这里有一个歧义,因为您可能希望它不会增长到 1x1 数组,而是增长到 1x10 数组,其他 9 个未直接分配的元素设置为默认值(即在双打的情况下为零或其他数字,或者在自定义类的情况下为默认元素)。但是,我认为唯一要说的是,这不是 MATLAB 所做的。

    分配这样一个空数组有意义吗?有哪些用例?

    一般来说,用例很少,实际上只是边缘情况。为了保持一致性,显然需要具有长度为零的数组的能力,但是 0x10 的数组在行为上与 0x0 的数组几乎没有太大的不同。

    如果我有一个高度可能不同但宽度始终为 10 的数组,我可能会将其预定义为 0x10 而不是 0x0,只是为了在代码中提醒自己这一事实。

    还要注意[]double.empty(0,0) 之间的行为存在差异。例如

    >> a = rand(4,2)
    a =
          0.83625      0.19468
          0.58508      0.12698
          0.44332       0.8509
          0.51858       0.3673
    >> a(2,:) = []
    a =
          0.83625      0.19468
          0.44332       0.8509
          0.51858       0.3673
    >> a(2,:) = double.empty(0,0)
    Subscripted assignment dimension mismatch. 
    >> a(2,:) = double.empty(0,2)
    Improper assignment with rectangular empty matrix.
    

    这是因为= [] 是一种特殊的 MATLAB 语法,用于删除行,而不是按字面意思构造空数组然后分配它。所以还有另一个用例,即防止意外删除行。

    【讨论】:

    • 所以&lt;Class&gt;.empty(1,numel(x)) 可以被一个简单的&lt;Class&gt;.empty() 替换,因为 MATLAB - 我慢慢明白了 - 无论如何都支持索引空字段,对吧?所以一个对象数组就像一个链表,我猜没有什么比预分配更重要
    • 我不确定您是如何从我的回答中得到这些想法的。首先,除非N 为零,否则&lt;Class&gt;.empty(1,N) 将出错,因此它很少等同于.empty()。其次,虽然我不确定“索引空字段”是什么意思,empty 不是字段,它是所有类的静态方法,它创建类的空数组(各种空维度,例如 0x0, 0x10、2x3x0x4x5)。对象数组实际上与链表完全不同,您绝对可以预先分配数组。但也许你所说的“预分配”对我来说意味着不同的东西。
    【解决方案2】:

    这不是与对象编程有关的问题,而是在 Matlab 中更普遍的正常行为。

    例如:

    >> a = NaN(0,10);
    >> a(1) = 5;
    >> a
    a =
        5 
    

    当您定义一个大小为0xn 的数组时,Matlab 不会为其分配任何内存,因为没有元素。因此,不应将调用 empty(0,10) 视为预分配。

    当您定义数组的第一个元素时,您强制调整大小,并且在调整大小期间,Matlab 始终采用数组的最小可能大小。

    empty 语法可用于定义一个数组,该数组将使用end+1 语法在循环中由聚合填充,例如:

    a = NaN(0,2);
    for i = 1:10
        a(end+1,:) = [i i^2];
    end
    

    最好的,

    【讨论】:

    • 您的最后一个示例实际上并没有使用 empty 方法——即使a 被预先分配为NaN(0,0),它的工作原理也完全相同。此外,最好将其预分配给NaN(10,2),然后用a(i, :) = 填充它。因此,尽管我知道您在说什么,但我不确定它是否真的按照问题的要求演示了 empty 的用例。
    猜你喜欢
    • 2015-09-17
    • 1970-01-01
    • 1970-01-01
    • 2011-11-05
    • 1970-01-01
    • 2016-01-01
    • 1970-01-01
    • 2013-08-23
    • 1970-01-01
    相关资源
    最近更新 更多