7

我不知道这里发生了什么。我正在使用 R2006b。在我提交错误报告之前,是否有可能使用较新版本的人进行测试以查看他们是否获得相同的行为?

代码: ( bug1.m)

function bug1
S = struct('nothing',{},'something',{});
add_something(S, 'boing');          % does what I expect
add_something(S.something,'test');  % weird behavior
end

function add_something(X,str)
    disp('X=');
    disp(X);
    disp('str=');
    disp(str);
end

输出:

>> bug1
X=
str=
boing
X=
test
str=
??? Input argument "str" is undefined.

Error in ==> bug1>add_something at 11
    disp(str);

Error in ==> bug1 at 4
add_something(S.something,'test');

看起来空虚/虚无S.something允许它转移函数调用的参数。这似乎是非常糟糕的行为。在短期内,我想绕过它(我正在尝试创建一个函数,将项目添加到最初为空的单元格数组中,该单元格数组是结构的成员)。

编辑:

推论问题:所以没有办法构造一个struct包含任何空单元格数组的文字?

4

4 回答 4

15

正如您自己已经发现的那样,这不是错误,而是“功能”。换句话说,这是STRUCT函数的正常行为。如果将空元胞数组作为字段值传递给 STRUCT,则假定您需要一个具有给定字段名称的空结构数组。

>> s=struct('a',{},'b',{})

s = 

0x0 struct array with fields:
    a
    b

要将空元胞数组作为实际字段值传递,您可以执行以下操作:

>> s = struct('a',{{}},'b',{{}})

s = 

    a: {}
    b: {}

顺便说一句,任何时候您想使用 STRUCT 将字段值设置为元胞数组都需要将其包含在另一个元胞数组中。例如,这将创建一个结构元素,其字段包含一个元胞数组和一个向量:

>> s = struct('strings',{{'hello','yes'}},'lengths',[5 3])

s = 

    strings: {'hello'  'yes'}
    lengths: [5 3]

但这会创建一个包含两个结构元素的数组,分布单元数组但复制向量:

>> s = struct('strings',{'hello','yes'},'lengths',[5 3])

s = 

1x2 struct array with fields:
    strings
    lengths

>> s(1)

ans = 

    strings: 'hello'
    lengths: [5 3]

>> s(2)

ans = 

    strings: 'yes'
    lengths: [5 3]
于 2009-06-02T13:44:16.163 回答
2

啊……我想我找到了答案。struct()具有多种行为,包括:

注意 如果任何值字段是空元胞数组 {},MATLAB 软件会创建一个空结构体数组,其中所有字段也为空。

显然,如果您将 0x0 结构的成员作为参数传递,它就像某种空幻像,并没有真正出现在参数列表中。(这仍然可能是一个错误)

错误2.m:

function bug2(arg1, arg2)
disp(sprintf('number of arguments = %d\narg1 = ', nargin));
disp(arg1);

测试用例:

>> nothing = struct('something',{})

nothing = 

0x0 struct array with fields:
    something

>> bug2(nothing,'there')
number of arguments = 2
arg1 = 
>> bug2(nothing.something,'there')
number of arguments = 1
arg1 = 
there
于 2009-06-02T13:39:35.860 回答
2

这种行为在 2008b 中仍然存在,实际上并不是真正的错误(尽管我不会说设计者打算这样做):当您进入 add_something(S,'boing') 并观看第一个参数时(比如选择它并按下 F9),你会得到一些与空结构 S 相关的输出。进入 add_something(S.something,'test') 并观察第一个参数,你会发现它实际上被解释为 'test' !

语法 struct.fieldname 旨在返回“逗号分隔列表”类型的对象。matlab 中的函数旨在接收这种确切类型的对象:参数名称按照传递的顺序赋予列表中的值。在您的情况下,由于第一个参数是一个空列表,因此函数接收的逗号分隔列表实际上从您传递的第二个值开始 - 即“测试”。

于 2009-06-02T13:42:11.223 回答
1

R2008b 中的输出相同:

>> bug1
X=
str=
boing
X=
test
str=
??? Input argument "str" is undefined.

Error in ==> bug1>add_something at 11
    disp(str);

Error in ==> bug1 at 4
add_something(S.something,'test');  % weird behavior
于 2009-06-02T13:35:26.633 回答