How do I create enumerated types in MATLAB?

前端 未结 10 2129
不知归路
不知归路 2020-12-02 17:04

Are there enumerated types in MATLAB? If not, what are the alternatives?

10条回答
  •  抹茶落季
    2020-12-02 17:34

    After trying out the other suggestions on this page, I landed on Andrew's fully object-oriented approach. Very nice - thanks Andrew.

    In case anyone is interested, however, I made (what I think are) some improvements. In particular, I removed the need to double-specify the name of the enum object. The names are now derived using reflection and the metaclass system. Further, the eq() and ismember() functions were re-written to give back properly-shaped return values for matrices of enum objects. And finally, the check_type_safety() function was modified to make it compatible with package directories (e.g. namespaces).

    Seems to work nicely, but let me know what you think:

    classdef (Sealed) Color
    %COLOR Example of Java-style typesafe enum for Matlab
    
    properties (Constant)
        RED = Color(1);
        GREEN = Color(2);
        BLUE = Color(3);
    end
    methods (Access = private) % private so that you can''t instatiate directly
        function out = Color(InCode)
            out.Code = InCode;
        end       
    end
    
    
    % ============================================================================
    % Everything from here down is completely boilerplate - no need to change anything.
    % ============================================================================
    properties (SetAccess=private) % All these properties are immutable.
        Code;
    end
    properties (Dependent, SetAccess=private)
        Name;
    end
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    methods
        function out = eq(a, b) %EQ Basic "type-safe" eq
            check_type_safety(a, b);
            out = reshape([a.Code],size(a)) == reshape([b.Code],size(b));
        end
        function [tf,loc] = ismember(a, b)
            check_type_safety(a, b);
            [tf,loc] = ismember(reshape([a.Code],size(a)), [b.Code]);
        end
        function check_type_safety(varargin) %CHECK_TYPE_SAFETY Check that all inputs are of this enum type
            theClass = class(varargin{1});
            for ii = 2:nargin
                if ~isa(varargin{ii}, theClass)
                    error('Non-typesafe comparison of %s vs. %s', theClass, class(varargin{ii}));
                end
            end
        end
    
        % Display stuff:
        function display(obj)
            disp([inputname(1) ' =']);
            disp(obj);
        end
        function disp(obj)
            if isscalar(obj)
                fprintf('%s: %s (%d)\n', class(obj), obj.Name, obj.Code);
            else
                fprintf('%s array: size %s\n', class(obj), mat2str(size(obj)));
            end
        end    
        function name=get.Name(obj)
            mc=metaclass(obj);
            mp=mc.Properties;
            for ii=1:length(mp)
                if (mp{ii}.Constant && isequal(obj.(mp{ii}.Name).Code,obj.Code))
                    name = mp{ii}.Name;
                    return;
                end;
            end;
            error('Unable to find a %s value of %d',class(obj),obj.Code);
        end;
    end
    end
    

    Thanks, Mason

提交回复
热议问题