Альтернативные варианты функции eval

Зачем избегать функции eval?

Хотя и eval функция очень мощная и гибкая, это не всегда лучшее решение задачи программирования. Код, который вызывает eval часто является менее эффективным и более трудным для чтения и отладки, чем код, который использует другие функции или языковые конструкции. Для примера:

  • MATLAB® компилирует код при первом запуске для повышения эффективности при будущих запусках. Однако, потому что код в eval оператор может измениться во время исполнения, он не скомпилирован.

  • Код в eval оператор может неожиданно создать или назначить переменной, уже находящейся в текущей рабочей области, перезаписав существующие данные.

  • Конкатенированные векторы символов в eval оператор часто трудно считать. Другие языковые конструкции могут упростить синтаксис в вашем коде.

Для многих распространенных применений evalсуществуют предпочтительные альтернативные подходы, как показано на следующих примерах.

Переменные с последовательными именами

Частое использование eval функция состоит в том, чтобы создать наборы переменных, таких как A1, A2, ..., An, но этот подход не использует степень обработки массива MATLAB и не рекомендуется. Предпочтительным способом является хранение связанных данных в одном массиве. Если наборы данных имеют различные типы или размеры, используйте структуру или массив ячеек.

Например, создайте массив ячеек, который содержит 10 элементов, где каждый элемент является числовым массивом:

numArrays = 10;
A = cell(numArrays,1);
for n = 1:numArrays
    A{n} = magic(n);
end

Доступ к данным в массиве ячеек осуществляется путем индексации фигурными скобками. Например, отобразите пятый элемент A:

A{5}
ans =
    17    24     1     8    15
    23     5     7    14    16
     4     6    13    20    22
    10    12    19    21     3
    11    18    25     2     9

Оператор назначения A{n} = magic(n) является более элегантным и эффективным, чем этот вызов к eval:

eval(['A', int2str(n),' = magic(n)'])     % Not recommended

Для получения дополнительной информации смотрите:

Файлы с последовательными именами

Связанные файлы данных часто имеют общее имя корня с целочисленным индексом, таким как myfile1.mat через myfileN.mat. Общее (но не рекомендуемое) использование eval функция состоит в том, чтобы создавать и передавать каждое имя файла функции с помощью синтаксиса команды, такого как

eval(['save myfile',int2str(n),'.mat'])     % Not recommended

Лучшая практика - использовать синтаксис функции, который позволяет передавать переменные в качестве входов. Для примера:

currentFile = 'myfile1.mat';
save(currentFile)

Вы можете создавать имена файлов в цикле, используя sprintf функция (которая обычно более эффективна, чем int2str), а затем вызвать save функция без eval. Этот код создает 10 файлов в текущей папке:

numFiles = 10;
for n = 1:numFiles
   randomData = rand(n);
   currentFile = sprintf('myfile%d.mat',n);
   save(currentFile,'randomData')
end

Для получения дополнительной информации смотрите:

Имена функции в переменных

Общее использование eval - выполнять функцию, когда имя функции находится в векторе символов. Существует два способа вычисления функций из переменных, которые более эффективны, чем использование eval:

  • Создайте указатели на функцию с @ символа или с str2func функция. Например, запустите функцию из списка, хранящегося в массиве ячеек:

    examples = {@odedemo,@sunspots,@fitdemo};
    n = input('Select an example (1, 2, or 3): ');
    examples{n}()
  • Используйте feval функция. Например, вызовите функцию построения графика (такую как plot, bar, или pie) с данными, которые вы задаете во время исполнения:

    plotFunction = input('Specify a plotting function: ','s');
    data = input('Enter data to plot: ');
    feval(plotFunction,data)

Имена полей в переменных

Доступ к данным в структуре с переменной именем поля путем добавления выражения для поля в круглые скобки. Для примера:

myData.height = [67, 72, 58];
myData.weight = [140, 205, 90];

fieldName = input('Select data (height or weight): ','s');
dataToUse = myData.(fieldName);

Если вы вводите weightв входе приглашении можно найти минимальный weight значение следующей командой.

min(dataToUse)
ans =
    90

Для дополнительного примера смотрите Сгенерировать имена полей из переменных.

Обработка ошибок

Предпочтительным методом обработки ошибок в MATLAB является использование try, catch оператор. Для примера:

try
   B = A;
catch exception
   disp('A is undefined')
end

Если ваша рабочая область не содержит переменной A, затем этот код возвращает:

A is undefined

Предыдущие версии документации для eval функция включает синтаксис eval(expression,catch_expr). При оценке expression вход возвращает ошибку, затем eval оценивает catch_expr. Однако явный try/catch значительно яснее, чем неявный улов в eval оператор. Использование неявного catch не рекомендуется.