我需要类似evalin
的内容,但Matlab的原始evalin
不能递归使用。例如,我有函数f0,它调用另外两个函数f11和f12:
function f0()
[v1, v2] = deal(1, 1);
f11();
f12();
disp(v1);
end
函数f11和f12使用变量v1,并且都调用函数f2:
function f11()
v1 = evalin('caller', 'v1');
f2();
assignin('caller', 'v1', v1);
end
function f12()
v1 = evalin('caller', 'v1');
f2();
assignin('caller', 'v1', v1);
end
函数f2应该使用f0&#39工作空间的变量v1和v2:
function f2()
v1 = evalin('caller', 'v1'); % get variable v1 from f11 or f12
% since there is already a variable v1
% in f11 and f12's workspaces
% TODO: get v2 from f0
if v2 == 1
v1 = v1 + 1;
end
assignin('caller', 'v1', v1);
end
有没有在f11和f12中不使用v2 = evalin('caller', 'v2')
的情况下使TODO成为可能?
答案 0 :(得分:3)
这可能是在功能之间组织数据传输的最糟糕方式之一。功能的工作区是有充分理由分开的,以保持整洁和有条理。
您正试图绕过设计此语言的人(以及许多其他共享工作空间/范围分离的语言)所实施的所有保护措施。这些“旁路”功能在Matlab中可用,以便在进行原型设计时准时使用。它们不是用于大量使用或最终解决方案(实际上大多数都不可编译)。
是
你在评论中说,由于数字的原因,传递变量作为参数是复杂的,但是每当你调用类似x = evalin('caller', 'x');
之类的东西时,你必须编写1行完整的代码来检索你的价值。然后assignin('caller', 'x', x);
是另一行代码发送回来......那很疯狂。
在函数输入参数中只有x
会不会更简单(也更短)? (在输入中有100个变量比要检索200个完整的代码行然后从不确定的位置重新发送这些值更快。)
为了让变量传递变得简单,您可以将它们全部收集到structure
(或cell array
)中:
[v1, v2] = deal(1, 1);
myVars.v1 = v1 ;
myVars.v2 = v2 ;
myVars = f11(myVars); %// you only have one variable to pass into your functions
myVars = f12(myVars); %// just make sure you retrieve it in output too
disp(myVars.v1);
然后
function myVars = f11()
myVars = f2(myVars);
end
依此类推,只要你将变量传递给下一个函数,然后在输出中检索它,这将适用于任何级别的递归。
如果您在f11()
内定义<{1}} 中的函数,则会共享2个函数中具有相同名称的变量(在两个层面都可见)。请阅读documentation
了解更多详情。通过这种方式,您不需要多次调用f0()
,因为变量随处可见。您的功能必须以这种形式编写:
evalin/assignin
Stack Exchange不会渲染它,但是在Matlab编辑器中你可以注意到“共享”变量将以不同的颜色突出显示(提醒你它们的范围与标准变量不同)。
如果我运行function f0()
[v1, v2] = deal(1, 1);
f11();
f12();
disp(v1);
function f11()
f2();
function f2()
if v2 == 1
v1 = v1 + 1;
end
end
end %// END function F11
function f12()
f2();
function f2()
if v2 == 1
v1 = v1 + 1;
end
end
end %// END function F12
end %// END function F0
,我会得到:
f0()
这是预期的结果。正如您所看到的,唯一的缺点是,如果您从>> f0
3
和f2()
内拨打f11()
,则必须在每个内容中编写f12()
函数(所以有点复制/粘贴)。除非在这种递归级别,你没有太多的变量要传递,所以你可以考虑在侧面编写f2()
并使用标准变量传递方案。
现在,如果您仍然热衷于编写多行代码来传递单个变量,那么仍然有两个选项:
global
变量setappdata
和getappdata
我不想使用f2()
所以我不会在这里详述。请记住,要使变量真正global
,必须在 每个 函数中将其声明为global
。
对于global
方法,您需要一个可以访问所有功能的“容器”。您可以使用“root”对象(标识符: appdata
)。
因此,例如,当您想要存储可以使用的变量时:
0
然后在你的任何函数中,获取值,处理它然后将其存储回来:
setappdata( 0 , 'v2' , v2 ) %// store the value of `v2` in a field named `'v2'` in the root object.
在基本函数和function f2()
v1 = getappdata(0,'v1') %// get the value of v1
v2 = getappdata(0,'v2') %// get the value of v2
if v2 == 1
v1 = v1 + 1; %// modify the value of v1
end
v1 = setappdata(0,'v1',v1) %// store the value of v1
end
,f11()
等中应用相同的原则...只需记住在修改它之后总是存储任何值,以便它可用于下一个函数需要它。
答案 1 :(得分:1)
试图做到这一点:你的变量&#39;持有一个值,该值应该与您希望对它们执行的操作保持一致。只是在黑暗中拍摄,但你在问题上尝试了面向对象。
classdef myObj
properties
v1;
v2;
end
methods
function f1(obj)
... do something here ....
obj.v1 = ....;
end
function f2(obj)
obj.f1();
end
end
根据您的具体问题,这可能是获得正确递归的最简单方法。 OO in Matlab isnt that hard to learn。
H个
答案 2 :(得分:0)
您可以将f0()
个变量保存到文件中,然后调用load
中的f2()
方法将这些变量导入f2()
工作区。