When I write some complex code with MATLAB, I want to prohibit modifying the fields of the structure after it is initialized.
For example, I initialize the following struct
s = struct('vec', zeros(3, 1), 'val', 1.0)
In the following process, I ALLOW modifying the value of fields:
s.vec(1) = 1;
s.val = 2;
I want to PROHIBIT modifying the size of the existing field and PROHIBIT adding a new field to the struct. If I run the following codes, I want it to return error information.
s.vec = zeros(4, 1);
s.mat = zeros(3, 3);
How to realize the above functions? Thank you!
CodePudding user response:
You need to write your own class, struct
does not have this functionality.
Below is an example, read the comments for more info.
In particular I'm creating a class with the two properties of your example, and adding input validation with validateattributes
and setter functions. The validateattributes
function issues descriptive errors without you having to write them.
With the below class saved on your path, you can then run
s = myObject('vec', zeros(3, 1), 'val', 1.0);
Where vec
and val
both default to NaN
(of the correct size) if not given as inputs. Then you can index like a struct to set the values, e.g.
s.vec(1) = 1; % Allowed, s.vec = [1 0 0] now
s.val = 2; % Allowed
s.vec = zeros(4,1); % Error: Expected input to be of size 3x1, but it is of size 4x1.
s.mat = zeros(3, 3); % Error: Unrecognized property 'mat' for class 'myObject'.
Full class example:
classdef myObject < matlab.mixin.SetGet
% We have to inherit from the SetGet superclass (could use a "handle"
% too) to get the setter functions
properties
% Object properties here which can be accessed using dot syntax
vec
val
end
methods
function obj = myObject( varargin )
% Constructor: called when creating the object
% Optional inputs for the properties to use name-value pairs
% similar to struct construction, with default values
p = inputParser;
p.addOptional( 'vec', NaN(3,1) );
p.addOptional( 'val', NaN(1,1) );
p.parse( varargin{:} );
% Assign values from inputs (or defaults)
obj.vec = p.Results.vec;
obj.val = p.Results.val;
end
% Use set functions. These are called when you try to update the
% corresponding property but allow for input validation before it
% is stored in the property.
function set.vec( obj, v )
validateattributes( v, {'numeric'}, {'size', [3,1]} );
obj.vec = v;
end
function set.val( obj, v )
validateattributes( v, {'numeric'}, {'size', [1,1]} );
obj.val = v;
end
end
end