«Ошибка» MATLAB (или действительно странное поведение) со структурами и массивами пустых ячеек
-
06-09-2019 - |
Вопрос
Я понятия не имею, что здесь происходит.Я использую 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