Тип-псевдоним для перечисления - PullRequest
1 голос
/ 04 мая 2020

Я работаю с некоторым кодом, который использует значения из класса enumeration (расширение uint8) для доступа к столбцам матрицы «по имени», а не по жестко заданному номеру. Причиной такого подхода является то, что матрицы воспринимаются как более производительные по сравнению с другими конструкциями, которые разрешают доступ к именованным полям (например, структуры / объекты или таблицы), что, предположительно, улучшает читаемость кода без ущерба для производительности.

Проблема в том, что что класс enum находится внутри пакета, давая ему довольно длинное имя. Это значительно ухудшает читабельность до такой степени, что почти полностью отрицает цель «именованных индексов»:

% 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 с тем же именем (см. мой собственный ответ ниже ), но мне интересно, есть ли " правильный "способ сделать это.

Ответы [ 2 ]

1 голос
/ 04 мая 2020

Одна альтернатива, которую вы могли бы рассмотреть, - это не использовать перечисление, а обычный класс с неизменяемыми свойствами. 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);
1 голос
/ 04 мая 2020

Один из вариантов - создать 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.

...