【问题标题】:Type-alias for enumeration枚举的类型别名
【发布时间】:2020-05-04 07:29:40
【问题描述】:

我正在使用一些代码,这些代码使用来自 enumeration 类(扩展 uint8)的值来“按名称”而不是通过硬编码数字访问矩阵列。采用这种方法的原因是,与其他允许命名字段访问的构造(例如结构/对象或表)相比,矩阵被认为具有更高的性能 - 据称这可以在不牺牲性能的情况下提高代码可读性。

问题是枚举类是在一个包中找到的,给它一个相当长的名字。这极大地损害了可读性,以至于几乎违背了“命名索引”的目的:

% What it looks like without using an enum:
val = foo(:, 7); % Magic number, :(

% Current situation (the enum is called "somePackage.SomeMeaningfulCollectionEnum"):
val = foo(:, somePackage.SomeMeaningfulCollectionEnum.varName1); % Very long name, :(

% Desired solution:
E = somePackage.SomeMeaningfulCollectionEnum; % This throws an error in R2020a
val = foo(:, E.varName1); % Short and descriptive!

当尝试使用上面的“期望的解决方案”时,我们得到以下错误:

Error using somePackage.SomeMeaningfulCollectionEnum
Cannot call the constructor of 'somePackage.SomeMeaningfulCollectionEnum' outside of its enumeration block.

我想出了一个解决方法,包括将每个枚举成员存储在具有相同名称的struct 字段中(请参阅my own answer below),但我想知道是否有“正确”的方法来做到这一点。

【问题讨论】:

    标签: matlab enums readability type-alias magic-numbers


    【解决方案1】:

    一种选择是创建一个struct,其字段是各个枚举成员:

    E = enumeration('somePackage.SomeMeaningfulCollectionEnum'); % Get all enumeration members
    E = [cellstr(E), num2cell(E)].'; % Prepares name-value pairs for `struct` creation
    E = struct(E{:});
    

    那么E实际上是somePackage.SomeMeaningfulCollectionEnum的类型别名,可以根据需要访问。

    另请参阅:enumeration

    【讨论】:

    • 有趣的方法。这实际上比使用table 更快吗?我知道table 很慢,但还是值得比较 IMO。
    • @Cris 添加到您的评论中:TMW 在recent blog post 中发布他们优化了 R2019b-R2020a 中的表格,所以是的,这绝对应该进行基准测试。
    【解决方案2】:

    您可以考虑的一种替代方法是不使用枚举,而是使用具有不可变属性的普通类。 somePackage.SomeMeaningfulCollectionEnum 将是:

    classdef SomeMeaningfulCollectionEnum
       properties (Constant)
          col1 = 1
          col2 = 2
          col3 = 3
       end
    end
    

    那么你可以这样做:

    E = somePackage.SomeMeaningfulCollectionEnum;
    val = foo(:, E.col1);
    

    我正在考虑的另一种方法是使用函数(传统上在 MATLAB 中用于定义常量),但我也无法做到这一点。我发现的最佳方法只是一个返回 OP 解决方案中创建的相同结构的函数:

    function out = SomeMeaningfulCollectionEnum
    out = struct('col1',1,'col2',2,'col3',3);
    

    现在你又可以这样做了:

    E = somePackage.SomeMeaningfulCollectionEnum;
    val = foo(:, E.col1);
    

    【讨论】:

    • 我认为在这种情况下Constant=trueimmutable 更合适。尽管如此,有效的解决方案。 +1
    • @Dev-iL:没错!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-09
    • 2015-11-16
    • 2010-12-09
    • 1970-01-01
    • 2014-08-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多