Matlab не может изменять параметры класса в конструкторе

Я вызываю функцию для изменения параметров моего класса внутри его конструктора, однако я не могу изменить значения. Это баг или специально?

В следующем примере я вызываю функцию calculateCalculatedProperties() внутри конструктора. calculateCalculatedProperties() вызывает функции Velocity() и Length(), которые устанавливают новые значения свойств скорости и длины. Однако в конечном продукте конструктора (экземпляре объекта) свойства не изменяются.

classdef piping
    %PIPING Summary of this class goes here
    %   Detailed explanation goes here
    
    properties 
        flowRate
        diameter
        startLocation location
        endLocation location
    end

    
    
    methods
        function self = piping(flowRate, diameter, startLocation, endLocation)
            
            self.flowRate = flowRate;
            self.diameter = diameter;
            self.startLocation = startLocation;
            self.endLocation = endLocation;
            
            self.calculateCalculatedProperties();
                       
        end
        
        function self = calculateCalculatedProperties(self)
            fprintf("hey")
            self.Velocity();
            self.Length();
        end
        
        
         function self = Velocity(self)
             self.velocity = self.flowRate / (pi * self.diameter^2 / 4);
         end
        
         function self = Length(self)
            self.length = location.calculateDistance(self.startLocation,self.endLocation) ;
            fprintf("hey this is lengthhhh")
            self.flowRate = 10000000;
         end

        
    end
    
    properties % Calculated properties
        
        velocity
        length
    end
end


person RedGermen    schedule 30.10.2020    source источник


Ответы (1)


Проблема здесь в том, что вы используете класс значения, а не класс дескриптора. Обратите внимание, что в вашем методе Velocity вы возвращаете экземпляр self, в классе значений эти вызовы метода возвращают отдельный объект, который игнорируется в этом коде.

При этом два возможных решения:

  1. Захватите выходные данные объектов-значений и верните окончательный измененный объект.

     function self = piping(flowRate, diameter, startLocation, endLocation)
         % ...
         self = self.calculateCalculatedProperties();      
     end
    
     function self = calculateCalculatedProperties(self)
         fprintf("hey")
         self = self.Velocity();
         self = self.Length();
     end
    
  2. Используйте классы дескрипторов для создания изменяемого объекта.

     classdef piping < handle
         % ...
     end
    

См. Сравнение классов дескрипторов и значений для получения дополнительной информации.

person GleasonK    schedule 30.10.2020
comment
Благодарю вас! Теперь все работает! Но у меня есть другой вопрос, почему я хочу сохранить свой класс как класс значений? - person RedGermen; 30.10.2020
comment
Это долгое обсуждение, но вкратце: классы значений позволяют вам программировать в безопасном стиле функционального программирования с минимальными побочными эффектами: они избегают псевдонимов ссылок на объекты, что приводит к общему изменяемому состоянию и возможным непреднамеренным побочным эффектам, и они позволяют вам изменять несколько полей объекта атомарным транзакционным способом. Кроме того, большинство вещей Matlab являются ценностью, а не обработкой/ссылкой, поэтому объекты-значения лучше работают с ними. Мое эмпирическое правило заключается в том, что в Matlab вам следует избегать классов дескрипторов, если они вам не нужны. - person Andrew Janke; 02.11.2020
comment
(Основная причина, по которой нужен объект дескриптора, заключается в том, что этот объект обертывает или содержит вещи, которые сами по себе являются подобными дескрипторам вещами передачи по ссылке, такими как графические дескрипторы Matlab, дескрипторы файлов, другие объекты дескрипторов Matlab, ссылки на объекты Java или другие объекты. вещи, которые ссылаются на состояние внешних общих ресурсов, таких как объекты файловой системы или соединения с базой данных.) - person Andrew Janke; 02.11.2020