鉴于使用动态变量是一种不好的做法(如上述 cmets 所述),在可能的“替代”解决方案中(这些也已在上述 cmets 中提出)使用 struct 数据类型可以考虑加上dynamic field names的使用。
dynamic field names 的优势在于可以“以编程方式”定义变量的名称(在这种情况下将是结构的字段),避免 eval 隐含的潜在危险。
此外,struct 的使用允许通过使用非常大的 related functions 集合以编程方式管理其字段及其内容。
在下面的“疯狂”实现中,dynamic field names 概念用于创建一组变量作为结构的字段。
特别是,代码允许创建:
-
一组变量(结构的字段),其名称在单元阵列中定义:
dynamic_vars={'Bucket','another_var','one_more_var'}
-
然后可以为每个变量指定数量(例如,4 Bucket => Bucket_1, Bucket_2, ...。数量在数组中指定
how_many=[4 3 2]
- 然后可以在单元格数组中指定变量的类型(
double、char、cell)
var_type={'double' 'char' 'cell'}
- 对于上述每个变量/结构的字段,可以通过
zeros、nan、ones 或string 等函数指定初始化它们的方法
init_set={'NaN' 'Hellp World' 'zeros'}
- 要完成变量的定义和初始化,可以使用单元数组设置它们的
size:
var_dim={[2 3] -1 [1 3] [2 3]}
这是完整的代码:
% Define the name of the variable
dynamic_vars={'Bucket','another_var','one_more_var'}
% Define how many variables to be created with the "dynamic_vars" names
how_many=[4 3 2]
% Define the type of the variable to be created
var_type={'double' 'char' 'cell'}
% Define the function or string to be used to initialize the variables
init_set={'NaN' 'Hellp World' 'zeros'}
%init_set={'NaN' 'Hellp World' 'char'}
% Define the size of the dynamic_vars tobe created
% In the case of cellarray:
% if cellarray of "number" two dimension have to be provided:
% size of the cellarray
% size of the content of the cellarray
% if cellarray of string to specify:
% the size of the cellarray
% the string to be used to initialize the cellarray
var_dim={[2 3] -1 [1 3] [2 3]}
%var_dim={[2 3] -1 [1 3] 'dummy_str'}
n_var=length(dynamic_vars)
% Loop over the variables to be created
for i=1:n_var
% Loop over the number of variables to be created
for j=1:how_many(i)
% Select the data type of the variable
switch(var_type{i})
% Create the i-th variable of the j-th type and iknitialize it
case 'double'
switch(init_set{i})
case 'zeros'
my_data.([dynamic_vars{i} '_' num2str(j)])=zeros([var_dim{i}])
case 'NaN'
my_data.([dynamic_vars{i} '_' num2str(j)])=nan([var_dim{i}])
case 'ones'
my_data.([dynamic_vars{i} '_' num2str(j)])=ones([var_dim{i}])
case 'rand'
my_data.([dynamic_vars{i} '_' num2str(j)])=rand([var_dim{i}])
otherwise
disp('ERROR: Unvalid init_set')
return
end
case 'char'
my_data.([dynamic_vars{i} '_' num2str(j)])=init_set{i}
case 'cell'
switch(init_set{i})
case 'char'
my_data.([dynamic_vars{i} '_' num2str(j)])=repmat({var_dim{i+1}},[var_dim{i}])
case 'zeros'
my_data.([dynamic_vars{i} '_' num2str(j)])=repmat({zeros(var_dim{i+1})},[var_dim{i}])
case 'NaN'
my_data.([dynamic_vars{i} '_' num2str(j)])=repmat({nan(var_dim{i+1})},[var_dim{i}])
case 'ones'
my_data.([dynamic_vars{i} '_' num2str(j)])=repmat({ones(var_dim{i+1})},[var_dim{i}])
case 'rand'
my_data.([dynamic_vars{i} '_' num2str(j)])=repmat({rand(var_dim{i+1})},[var_dim{i}])
otherwise
disp('ERROR: Unvalid init_set')
return
end
otherwise
disp('ERROR: Unvalid data type')
return
end
end
end
my_data
生成具有以下字段的结构my_data:
Bucket_1
Bucket_2
Bucket_3
Bucket_4
another_var_1
another_var_2
another_var_3
one_more_var_1
one_more_var_2
初始化如下:
Bucket_1 =
NaN NaN NaN
NaN NaN NaN
Bucket_2 =
NaN NaN NaN
NaN NaN NaN
Bucket_3 =
NaN NaN NaN
NaN NaN NaN
Bucket_4 =
NaN NaN NaN
NaN NaN NaN
another_var_1 = Hellp World
another_var_2 = Hellp World
another_var_3 = Hellp World
one_more_var_1 =
{
[1,1] =
0 0 0
0 0 0
[1,2] =
0 0 0
0 0 0
[1,3] =
0 0 0
0 0 0
}
警告
- 必须添加对输入一致性的控制(例如,
dynamic_vars 和 how_many 的长度必须相同,...)
- 代码已经用 Octave 4.2.1 测试过