How do I create enumerated types in MATLAB?

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

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

相关标签:
10条回答
  • 2020-12-02 17:29

    You could also use Java enum classes from your Matlab code. Define them in Java and put them on your Matlab's javaclasspath.

    // Java class definition
    package test;
    public enum ColorEnum {
        RED, GREEN, BLUE
    }
    

    You can reference them by name in M-code.

    mycolor = test.ColorEnum.RED
    if mycolor == test.ColorEnum.RED
        disp('got red');
    else
        disp('got other color');
    end
    
    % Use ordinal() to get a primitive you can use in a switch statement
    switch mycolor.ordinal
        case test.ColorEnum.BLUE.ordinal
            disp('blue');
        otherwise
            disp(sprintf('other color: %s', char(mycolor.toString())))
    end
    

    It won't catch comparisons to other types, though. And comparison to string has an odd return size.

    >> test.ColorEnum.RED == 'GREEN'
    ans =
         0
    >> test.ColorEnum.RED == 'RED'
    ans =
         1     1     1
    
    0 讨论(0)
  • 2020-12-02 17:34

    There is actually a keyword in MATLAB R2009b called 'enumeration'. It seems to be undocumented, and I cannot say I know how to use it, but the functionality is probably there.

    You can find it in matlabroot\toolbox\distcomp\examples\+examples

    classdef(Enumeration) DmatFileMode < int32
    
        enumeration
            ReadMode(0)
            ReadCompatibilityMode(1)
            WriteMode(2)
        end
    <snip>
    end
    
    0 讨论(0)
  • 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

    0 讨论(0)
  • 2020-12-02 17:35

    If you need the enumerated types just for passing to C# or .NET assembly, you can construct and pass the enums with MATLAB 2010:

    A = NET.addAssembly(MyName.dll)
    % suppose you have enum called "MyAlerts" in your assembly
    myvar = MyName.MyAlerts.('value_1');
    

    you can also check the official MathWorks answer at

    How do I use .NET enumerated values in MATLAB 7.8 (R2009a)?

    // the enum "MyAlerts" in c# will look something like this
    public enum MyAlerts
    {
        value_1 = 0,
        value_2 = 1,
        MyAlerts_Count = 2,
    }
    
    0 讨论(0)
提交回复
热议问题