Matlab中评估函数内的控制流
Posted
技术标签:
【中文标题】Matlab中评估函数内的控制流【英文标题】:Control flow within an eval function in Matlab 【发布时间】:2014-08-10 18:20:53 【问题描述】:如果我将 continue
作为 eval()
指令的参数包含在内,则它不会按预期工作。例如,执行以下代码时:
listParam = 'a','b','c';
a = 17;
b = NaN;
c = 4;
for ii=1:numel(listParam),
eval(['if isnan(',listParamii,'), continue; end']);
disp(['The parameter ', listParamii, ' is not a NaN.']);
end
会提示错误:
Error: A CONTINUE may only be used within a FOR or WHILE loop.
有人知道为什么吗?
注意:我知道我应该避免使用eval()
,并且可以将前面的示例重构为更好的编码;但我发现了一个奇怪的行为,我很好奇发生了什么。
【问题讨论】:
【参考方案1】:您传递给eval
的表达式本身必须是一个有效的matlab 表达式,不考虑任何周围的代码。这意味着每个continue
必须被一个循环包围。要么将周围的for
放在您的评估中,要么将continue
放在外面。
【讨论】:
+1 关于eval
的参数是独立于“正常”代码进行评估这一事实的任何参考?
我更新了我的答案以使其准确。 @LuisMendo:我没有任何参考,但据我了解,代码根本不是有效的表达方式。
@LuisMendo 关于eval
的范围,我做了一些简单的实验;如果将continue
放在单独的foo.m
脚本中(单行表示continue
),并且在主脚本中使用eval('foo')
,则for
循环将得到控制。
@Yvon 这很有趣!【参考方案2】:
正如@Daniel 所指出的,eval
由脚本调用,而不是由for
循环直接控制。你可以这样想:eval
中的continue
会将程序计数器移动到eval
内代码的头部,但不会移动到for
循环的头部;这当然会失败,因为 Matlab 不允许在行之间跳转。
continue
只能直接出现在 for
或 while
循环内。但是,您可以像这样破解代码:
for ii=1:numel(listParam),
eval(['if isnan(',listParamii,'), x=1; else, x=0; end']);
if x
continue;
end
disp(['The parameter ', listParamii, ' is not a NaN.']);
end
奇怪的是,x
恰好出现在脚本的堆栈中。然而,这远非一段好的代码。永远不要使用这种方法。
编辑:关于eval
的“控制”范围。
我不是在谈论eval
的变量范围/工作区。提示可以在多个文档中找到,例如 this 和 this。简而言之,eval
使用“当前”工作区。
但是,我发现以下一些有趣的事情:
直接在eval
中运行continue
for ii = 1:2
eval('continue')
ii+10
end
这根本失败,如问题所示。错误是Error: A CONTINUE may only be used within a FOR or WHILE loop.
,这意味着eval
内的continue
找不到任何循环(for
循环)。
在for
循环中调用单独的脚本
for ii = 1:2
foo
ii+10
end
而脚本foo.m
是
ii
continue
首先,在foo.m
Mlint 给出了一个红线警告,这通常表示一个可以阻止代码运行的错误,说CONTINUE is only valid in a FOR or WHILE loop
。但是在 foo.m
上按 F5 没有任何问题 - 事实上,在任何地方运行单个 continue
不会导致代码崩溃。
运行主脚本给出输出
ii =
1
ii =
2
>>
....所以foo.m
捕获for
循环?
eval('foo')
- 我真的不懂Matlab
for ii = 1:2
eval('foo')
ii+10
end
结果让我有点吃惊。
ii =
1
ans =
11
ii =
2
ans =
12
>>
想法:eval
在独立的控制流中运行代码,但与当前的共享其工作区。它(但不完全是)类似于isolated world 模型,其中(在 Matlab 中)不同的代码段可以与同一组变量交互,但在控制流的意义上不能相互交互。
不幸的是,我无法找到任何现有资源作为参考来证明这个想法。
这不会改变我的解决方案:无论如何,尽量避免使用eval
。
【讨论】:
以上是关于Matlab中评估函数内的控制流的主要内容,如果未能解决你的问题,请参考以下文章