«Ошибка» MATLAB (или действительно странное поведение) со структурами и массивами пустых ячеек

StackOverflow https://stackoverflow.com/questions/939544

Вопрос

Я понятия не имею, что здесь происходит.Я использую 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 литерал, содержащий массивы пустых ячеек?

Это было полезно?

Решение

Как вы уже сами убедились, это не ошибка, а «фича».Другими словами, это нормальное поведение СТРУКТУРА функция.Если вы передаете массивы пустых ячеек в качестве значений полей в 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]

Другие советы

ААА...Думаю, я нашел ответ. struct() имеет несколько вариантов поведения, в том числе:

Примечание. Если какое -либо из полей значений является пустой массией ячеек {}, программное обеспечение Matlab создает пустой структуру, в котором все поля также пусты.

и, очевидно, если вы передаете член структуры 0x0 в качестве аргумента, это похоже на какой-то пустой фантом, который на самом деле не отображается в списке аргументов.(это все еще, вероятно, ошибка)

ошибка2.м:

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

Такое поведение сохраняется и в 2008b, и на самом деле это не ошибка (хотя я бы не сказал, что дизайнеры задумали это):Когда вы войдете в add_something(S,'boing') и посмотрите первый аргумент (скажем, выделив его и нажав F9), вы получите некоторый вывод, относящийся к пустой структуре S.Войдите в add_something(S.something,'test') и посмотрите первый аргумент, и вы увидите, что он фактически интерпретируется как 'test'!

Синтаксис struct.fieldname предназначен для возврата объекта типа «список, разделенный запятыми».Функции в Matlab предназначены для получения объекта именно такого типа:имена аргументов присваиваются значениям в списке в порядке их передачи.В вашем случае, поскольку первый аргумент является пустой список, список, разделенный запятыми, который получает функция, на самом деле начинается со второго значения, которое вы передаете, а именно с «теста».

Вывод идентичен в 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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top