我将以下函数作为我继承的大型代码库的一部分:
function = save_function(fpath, a,b,c)
save(fpath, 'a', 'b', 'c')
end
在执行另一个脚本之前,在一个脚本的末尾调用此函数。这样,变量名称被正确保存(糟糕的设计,我知道 - 我没有写这段代码)。
现在,我正在对代码库进行更改,并意识到我需要在fpath
中存储更多变量。我面临两个选择:
save_function
以接受更多输入。这将破坏代码库中也使用此函数的任何其他代码save_function2(a, b, c, d, e, ...)
。这似乎也是糟糕的设计。我理想的做法是允许save_function
一次接收任意数量的参数,并通过传入的变量名保存它们。
完成了一些谷歌搜索后,我找到了eval
和eval_in
,它们将字符串评估为matlab代码。但是,使用它有两个问题:
eval
非常慢且非常危险to_string
函数为了对抗灵活数量的变量,我决定使用varargin
和inputname
,如下所示:
function = save_function(fpath, varargin)
names = {}
for i=1:size(varargin,1)
names{i} = inputname(i+1); % have to offset by 1 to account for fpath
end
save(fpath, names{:});
end
不幸的是,由于输入变量保存在varargin
中,因此它们在堆栈中不作为变量名存在,因此save
行失败
如何使用变量名称在堆栈上动态创建这些变量?
答案 0 :(得分:2)
您可以使用结构动态定义已保存的变量名称 此选项记录在here。
function save_function( fpath, varargin )
for ii = 1:numel( varargin )
st.( inputname(ii+1) ) = varargin{ii};
end
save( fpath, '-struct', 'st' );
根据经验,structure with dynamic field names在动态变量名称方面往往优于eval
或assignin
。
答案 1 :(得分:0)
诀窍是使用assignin
,它带有工作空间,变量名和一些数据。然后,它在指定的工作空间中创建一个具有给定名称的变量,其值为数据:
assignin(workspace, varname, value)
工作区标识符可以是'caller'
或'base'
。前者在函数的工作空间中创建变量,该变量调用调用assignin
的函数;而后者...我不知道 - 它似乎没有把变量放在我能看到的任何地方。
诀窍是创建一个小函数来将变量分配给调用工作区,并从assignin
内调用此函数:
function = save_function(fpath, varargin)
names = {}
for i=1:size(varargin,1)
names{i} = inputname(i+1); % have to offset by 1 to account for fpath
end
create_variables(names, varargin);
save(fpath, names{:});
end
function = create_variables(names, vals)
for i=1:size(names, 1)
assignin('caller', names{i}, vals{i});
end
end