Геттеры и сеттеры внутри объекта - PullRequest
0 голосов
/ 27 октября 2018

У меня есть объект с именем TestData (), который обрабатывает данные и помещает их в файл в указанном формате.Одним из свойств является data, которое хранится в виде массива типа double.Вот объект и его конструктор:

classdef TestData
properties
    metaData  = [];  % stores meta data in Nx2 array
    data      = [];  % stores data in PxQ array
    colLabels = [];  % labels columns
    colUnits  = [];  % provides units
    metaPrint % used to print metaData
    temp      % debugging purposes only
end

methods
    %****************************************************************************%
    %Function: TestData
    %Purpose:  Constructor used to allocate data arrays
    %****************************************************************************%
    function this = TestData() %constructor
        this.metaPrint  = [];
        this.temp       = [];
    end %TestData()     

Данные, помещаемые в объект, поступают из файла .m, внешнего по отношению к объекту, например:

myTestData=TestData; % Generate an instance of the object

% Data
ErrorLine1 = zeros([length(ErrorLine')+2 1]); % Empty Vector to store 11X1 
ErrorLine data
ErrorLine1(2:end-1) = ErrorLine(1:end);
mat = [Avec' Bvec' Invec' Ovec' ErrorLine1 PercentErrorOD'];
myTestData.data = mat;    

Итак, когда я устанавливаю myTestData.data = mat, это помещает данные в объект, но затем вызывает функции получения и установки для этого объекта.Одной из основных причин использования этих функций является фильтрация данных и определение, является ли это правильный тип данных (в этом случае формат должен быть double).Однако, когда я пытаюсь сделать это в коде, это не работает.Вот что я написал для получателя:

    function data = get.data(this)
        data = this.data;
    end %getData

И установщик:

    function this = set.data(this, data)
        i = arrayfun(@(n)strcmp(class(this.data(n)), 'doube'), 1:numel(this.data)); %#ok<STISA>
        disp(i)
        if any(i == 0)
            disp("WE HAVE A ZERO")
            msg = "Data in object's 'data' property is not of type double";
            error(msg);

        else
            this.data = data;
            disp('Hi from setter')
        end
    end % set.data 

Если я запускаю функциональность strcmp и any через командное окно, это работает!Когда я запускаю его из редактора, он всегда отображает строку «Hi from setter», даже если я изменяю «double» в сравнении на «string».Поэтому я просто не уверен, почему он не входит в оператор if.

Если в моем коде есть что-то, что можно изменить, чтобы сделать его более эффективным, пожалуйста, дайте мне знать.Кроме того, если есть что-то еще, я могу сделать все возможное.Заранее спасибо!

1 Ответ

0 голосов
/ 27 октября 2018

В вашем сеттере у вас есть эта строка:

i = arrayfun(@(n)strcmp(class(this.data(n)), 'doube'), 1:numel(this.data));

Но учтите, что здесь вы еще не сделали this.data = data. Когда вы проверяете this.data, вы проверяете старое значение свойства, а не значение, которое вы хотите присвоить. Вам нужно проверить data.

Вместо использования strcmp для результата class, вы можете лучше протестировать с помощью isa. Кроме того, если data не является массивом ячеек или массивом структур, каждый из элементов всегда будет одного и того же класса. Вам не нужно перебирать весь массив, чтобы проверить его тип, просто посмотрите на тип самого массива. В случае массива ячеек и массива структуры индексирование должно быть различным для извлечения элементов. Таким образом, data(n) всегда будет иметь тот же тип, что и data. Таким образом, ваш сеттер может быть записан как:

function this = set.data(this, data)
   if ~isa(data,'double')
      error('WRONG!')
   end
   this.data = data;
end

Еще одна проблема с кодом: if any(i == 0). any сворачивает одно измерение входного массива. Таким образом, если i является 2D-матрицей, то на выходе получается вектор строки. Каждый элемент будет истинным, если любой из элементов в данном столбце истинен. Оператор if является истинным, только если все элементы данного выражения отличны от нуля. Это означает, что все столбцы должны иметь хотя бы одно значение 0 для запуска этого выражения.

Вместо этого сделайте if any(i(:)==0). Здесь мы превращаем i в вектор-столбец (это не копирует данные, это эффективно), и, таким образом, any возвращает единственное (скалярное) значение. Если у вас есть MATLAB R2018b, то вы также делаете if any(i,'all'), что эквивалентно.

Вы часто будете видеть код, выполняющий if any(any(i==0)), но это не работает, если i имеет три или более измерений. Это также неэффективно, формы выше лучше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...