空的 Matlab 结构体 S 和所有元素 S(:) 之间的区别

7
我的问题是: 如果 S 是一个空结构体,那么 SS(:) 有什么区别。
我相信它们之间存在差异,因为有这样的问题: 向空结构体添加字段 最简示例:
S = struct(); %Create a struct
S(1) = []; %Make it empty
[S(:).a] = deal(0); %Works
[S.b] = deal(0); %Gives an error

错误信息:

当结构为空时,点名称结构赋值是非法的。请在结构上使用下标。

3个回答

7
实际上,这里还有一个奇怪的问题需要解决:
>> S = struct('a',{}, 'b',{})
S = 
0x0 struct array with fields:
    a
    b

>> [S(:).c] = deal()
S = 
0x0 struct array with fields:
    a
    b
    c

>> S().d = {}          %# this could be anything really, [], 0, {}, ..
S = 
0x0 struct array with fields:
    a
    b
    c
    d

>> S = subsasgn(S, substruct('()',{}, '.','e'), {})
S = 
0x0 struct array with fields:
    a
    b
    c
    d
    e

>> S = setfield(S, {}, 'f', {1}, 0)
S = 
0x0 struct array with fields:
    a
    b
    c
    d
    e
    f

现在进入有趣的部分,我发现了一种导致MATLAB崩溃的方法(已在R2013a上进行了测试):

%# careful MATLAB will crash and your session will be lost!
S = struct();
S = setfield(S, {}, 'g', {}, 0)

3
好的!我确认在 R2012b 和 R2012a 上发生了段错误。 - Jonas
我刚在Matlab 2014b上尝试了一下,结果还是崩溃了。真有趣。 - David Kelley
1
不再在2015b和2016b上崩溃。 - Florian Castellane

4

[S(:).b] = deal(0)相当于[S(1:end).b] = deal(0),扩展为[S(1:numel(S)).b] = deal(0),或者在您特定的情况下[S(1:0).b] = deal(0)。因此,您未对结构体的任何元素进行操作,我希望它能起作用,尽管我仍然觉得这将添加一个字段b有些令人惊讶。也许正是这种特殊的怪异性,只能通过明确指定字段列表来访问,导致了错误。

请注意,如果您想创建一个具有字段b的空结构体,您可以选择编写以下代码:

S(1:0) = struct('b',pi) %# pie or no pie won't change anything

虽然这会生成一个0x0的结构体。

0

实际上,SS(:)之间的区别适用于结构体,而不仅仅是空结构体。

这种情况可能发生的一个原因是,这样可以选择访问结构体还是其内容。

一个实际的例子是使用[]进行赋值以删除某些内容:

S = struct();
T = struct();

S(:) = []; % An empty struct with all fields that S used to have
T = []; % Simply an empty matrix

S现在是一个空结构体,但仍然包含它之前拥有的所有字段。

另一方面,T现在已经变成了简单的空矩阵[]

这两个操作都符合您的预期,如果没有结构体及其所有元素之间的区别,这将是不可能的。


在检查它的泛化如何时,我遇到了这个问题:https://dev59.com/3nfZa4cB1Zd3GeqPOCjM - Dennis Jaheruddin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接