matlab定义枚举类的三种方式
在 MATLAB 中,最常见的“枚举”用法是基于 classdef 定义的枚举类(Enumeration Class),以及在 Simulink 等场合下常用的 Simulink.defineIntEnumType 方法。下面分别做简要说明
1. 基于 classdef 的枚举类
MATLAB 提供了一种面向对象的方式来创建枚举类型:在 classdef 文件中,通过 enumeration
关键字列出所有枚举成员。最简单的形式如下:
classdef(Enumeration) MyColor
enumeration
Red, % 枚举成员1
Green, % 枚举成员2
Blue % 枚举成员3
end
end
classdef(Enumeration) MyColor
表示定义一个名为MyColor
的枚举类。enumeration ... end
块内列出了该枚举类所有的离散成员。
1.1 带基础数值类型的枚举
在某些情况下我们希望枚举拥有一个“底层数值类型”(例如 int8
, int32
等),以及具体的值映射。例如:
classdef(Enumeration) Grade < int32
enumeration
A(4)
B(3)
C(2)
D(1)
F(0)
end
end
- 此处
Grade < int32
指定了枚举类的底层类型是int32
。 A(4), B(3), ...
等语法表示每个枚举成员对应的数值。
1.2 为枚举添加属性和方法
虽然是枚举,MATLAB 仍允许我们在类中定义只读属性或静态方法等。例如:
classdef(Enumeration) Fruit < int32
enumeration
Apple(1)
Banana(2)
Cherry(3)
end
properties(Constant)
Description = "This is a Fruit enumeration class."
end
methods(Static)
function result = isCitrus(fruit)
% 判断是否属于柑橘类,这里仅做演示
result = (fruit == Fruit.Cherry);
end
end
end
这样我们就可以调用 Fruit.Description
或 Fruit.isCitrus(Fruit.Cherry)
等方法/属性。
2. 基于 Simulink.defineIntEnumType 的枚举
当需要在 Simulink 或 Stateflow 等环境下使用枚举类型(尤其用于生成可移植的 C/C++ 代码)时,可以使用 Simulink.defineIntEnumType
定义。它通常在脚本或函数中被调用,以在 MATLAB 工作区或 Simulink 模型范围内注册一个枚举类型。例如:
Simulink.defineIntEnumType(...
'TrafficLightState', { 'Red','Yellow','Green' }, ...
[0;1;2], ...
'Description', 'Traffic light states', ...
'HeaderFile', 'TrafficLightState.h', ...
'DataScope', 'Exported' ...
);
'TrafficLightState'
是该枚举类型名称。{ 'Red','Yellow','Green' }
是枚举成员列表。[0;1;2]
定义了每个成员对应的数值。- 后面的
'Description'
、'HeaderFile'
等参数可选,用于指定其他信息(如代码生成时的头文件等)。
这种方法常见于 Simulink/Stateflow/嵌入式代码生成场景。
在绝大多数 MATLAB 脚本或函数开发时,如果需要枚举类型,一般建议采用 classdef 的方式;而在 Simulink/嵌入式开发场景,则常用 Simulink.defineIntEnumType。根据您的需求选择合适的方法即可。
在 MATLAB/Simulink 环境下,Simulink.defineIntEnumType
函数可以在工作区/模型中注册一个整型枚举类型,并为生成代码等提供配置信息。它的常用调用形式通常如下:
Simulink.defineIntEnumType(...
'TypeName', ... % 枚举类型的名称(字符串)
{'Enum1','Enum2',...}, ... % 枚举成员名称的元胞数组
[val1 val2 ...], ... % 与枚举成员对应的数值数组
'Name1', Value1, ... % 可选的 Name-Value 参数对
'Name2', Value2, ...
...);
下面列出了该函数支持的常用 Name-Value 参数,并对各参数的作用进行说明。
3. 常用必需参数
-
'TypeName'
- 第一个参数(字符串),指定该枚举类型名称,例如
'TrafficLightState'
。 - 注意:这是通过字符串传递给函数,不是 Name-Value 格式的配置参数。
- 第一个参数(字符串),指定该枚举类型名称,例如
-
'Members'
- 第二个参数(元胞数组),枚举成员名称列表,例如
{'Red','Yellow','Green'}
。 - 同样这是直接传递给函数的非 Name-Value 参数。
- 第二个参数(元胞数组),枚举成员名称列表,例如
-
'IntValues'
- 第三个参数(数值数组),为各枚举成员定义实际对应的整型值,例如
[0 1 2]
。 - 同样属于基本调用参数,而非可选的 Name-Value。
- 第三个参数(数值数组),为各枚举成员定义实际对应的整型值,例如
4. 常用 Name-Value 参数
调用 Simulink.defineIntEnumType
时可以在后面跟若干 Name-Value
对,用来设置在 Simulink 及 代码生成 中的一些行为或属性,常见的包括:
-
'Description'
- 用于给该枚举类型添加文字描述(仅在 MATLAB/Simulink 环境内可见,不影响实际数值)。
- 例:
'Description','Traffic light states'
-
'DataScope'
- 指定在生成代码时该枚举类型的“可见性”或“作用域”。常见取值包括:
'Auto'
(默认):自动处理'Imported'
:外部已定义,不在生成的代码中重复定义'Exported'
:在生成的代码中导出定义'ImportedExtern'
:类型以extern
方式在外部定义'ImportedInclude'
:类型通过外部头文件(#include
)提供
- 其目的是告诉代码生成器:该枚举在目标 C/C++ 环境中应如何声明或引用。
- 指定在生成代码时该枚举类型的“可见性”或“作用域”。常见取值包括:
-
'HeaderFile'
- 指定该枚举类型对应的头文件名称。
- 当
DataScope
为'Exported'
或'ImportedInclude'
等时,代码生成器会将类型的声明或引用放到该头文件中。 - 例:
'HeaderFile','TrafficLightState.h'
-
'DefaultValue'
- 指定该枚举类型的默认值(成员名的字符串),用于 Simulink 在缺省情况下初始化此类型的变量。
- 例如:
'DefaultValue','Red'
表示枚举的默认值是Red
。
-
'AddClassNameToEnumNames'
{'on'|'off'}
,用来控制在生成的 C/C++ 代码中,枚举值名称是否带上“枚举类型名”作为前缀。- 如果
'on'
,则生成代码里的枚举常量名会类似TrafficLightState_Red
;如果'off'
则可能只出现Red
。 - 视代码风格或命名空间冲突需求来选择。
-
'CharType'
{'uint8'|'uint16'}
,用于指定生成的枚举类型在 Stateflow 等环境中(或在 MATLAB 内部)对字符串存储时,使用uint8
还是uint16
。- 如果涉及多语言或包含超出 ASCII 的字符集需求,可以使用
uint16
;仅英文/ASCII 则可使用uint8
。
-
'PackageName'
(可能更旧或有时才出现)- 指定该枚举类应该放在哪个 MATLAB 包下,类似
+PackageName
的包。 - 一般在仅 MATLAB OO 类枚举中才使用得更多,在 Simulink 定义中不常见。
- 指定该枚举类应该放在哪个 MATLAB 包下,类似
注意:实际可用的 Name-Value 选项可能会因不同版本的 MATLAB/Simulink 而略有差异,以上列出的为常见用法。
4. 参数示例
综合示例:
Simulink.defineIntEnumType(...
'TrafficLightState', ...
{'Red','Yellow','Green'}, ...
[0;1;2], ...
'Description','Traffic light states', ...
'DataScope','Exported', ...
'HeaderFile','TrafficLightState.h', ...
'DefaultValue','Red', ...
'AddClassNameToEnumNames','on' ...
);
'TrafficLightState'
:定义枚举类型名称{'Red','Yellow','Green'}
:三个枚举成员[0;1;2]
:对应的数值'Description','Traffic light states'
:描述'DataScope','Exported'
:代码生成时会把类型定义导出到生成的文件中'HeaderFile','TrafficLightState.h'
:类型声明/定义所在的头文件'DefaultValue','Red'
:默认值是Red
'AddClassNameToEnumNames','on'
:生成的 C/C++ 代码中,枚举名称会带前缀,例如TrafficLightState_Red
这样,Simulink 就会在进行模型编译/代码生成时知道如何处理此自定义的整型枚举类型。
5. 参数小结
- 必需参数
nameOfEnumerationType
(枚举类型名)members
(枚举成员名称列表)intValues
(枚举成员对应整型值)
- 常用可选参数
Description
:对枚举类型的文本描述DataScope
:控制代码生成时的导入/导出方式HeaderFile
:指定头文件名,用于生成或包含枚举声明DefaultValue
:Simulink 下该枚举类型变量的缺省值AddClassNameToEnumNames
:控制枚举常量在生成代码中的命名风格CharType
:控制字符串存储格式(uint8
/uint16
)
通过以上参数的配置,就可以让 Simulink 在仿真、代码生成、建模等过程中正确地识别并使用自定义枚举类型。
6. 数据字典定义枚举
使用数据字典的方式一般结合Simulink模型使用。
% 创建一个名为 'MyDictionary.sldd' 的数据字典
dictObj = Simulink.data.dictionary.create('MyDictionary.sldd');
打开数据字典文件
添加枚举变量
添加一个枚举
使用数据字典的方式添加枚举方式完成。
3. 将数据字典附加到模型
打开你的 Simulink 模型。
在模型窗口中,选择 Model Explorer(快捷键 Ctrl+E)。
在 Model Explorer 中,右键单击模型名称,选择 Data Dictionary -> Attach。
在弹出的对话框中,找到并选择你之前创建或打开的数据字典文件。