Main Content

eval 函数的替代方法

为什么要避免使用 eval 函数?

虽然 eval 函数非常强大和灵活,但它并不总是编程问题的最佳解决方案。与使用其他函数或语言构造的代码相比,调用 eval 的代码通常效率较低,而且难以阅读和调试。例如:

  • MATLAB® 会在您首次运行代码时对代码进行编译,以增强以后运行的性能。但是,由于 eval 语句中的代码可在运行时更改,因此无法进行编译。

  • eval 语句中的代码可能会意外创建变量或为当前工作区中已存在的变量赋值,并覆盖现有的数据。

  • eval 语句中的串联字符向量通常难以阅读。其他语言构造方式可以简化您代码中的语法。

对于 eval 的许多常见用法,有一些首选的替代方法,下面以示例形式介绍了这些方法。

带有序列名称的变量

eval 函数的常见用法是创建 A1A2...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.matmyfileN.mateval 函数的一个常见(但不建议)用法是使用命令语法构造每个文件名并将它们传递给某个函数,例如

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 函数。例如,使用您在运行时指定的数据调用绘图函数(例如 plotbarpie):

    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。但是,在 eval 语句中,显式的 try/catch 明显比隐式的 catch 更清晰。建议不要使用隐式的 catch。