MATLAB “bug” (o un comportamento davvero strano), con le strutture e gli array di celle vuote
-
06-09-2019 - |
Domanda
Non ho idea di quello che sta succedendo qui. Sto utilizzando R2006b. C'è qualche possibilità che qualcuno là fuori con una versione più recente potuto testare per vedere se ottengono lo stesso comportamento, prima di aprire un bug report?
Codice: (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
uscita:
>> 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');
Sembra che il vuoto / nulla di S.something
permette di spostare gli argomenti per una chiamata di funzione. Questo mi sembra molto cattivo comportamento. A breve termine che voglio trovare via intorno ad esso (sto cercando di fare una funzione che aggiunge elementi a un array di celle inizialmente vuoto che è un membro di una struttura).
Modifica
domanda Corollario: quindi non c'è modo di costruire un struct
letterale contenente gli array di celle vuote
Soluzione
Come già te scoperto, questo non è un bug, ma una "caratteristica". In altre parole, è il comportamento normale del STRUCT funzione. Se passate di matrici di celle vuote come valori di campo a struct, si presuppone che si desidera un array struttura vuota con il dato nomi di campo.
>> s=struct('a',{},'b',{})
s =
0x0 struct array with fields:
a
b
Per passare una matrice cella vuota come un valore di campo effettivo, si dovrebbe effettuare le seguenti operazioni:
>> s = struct('a',{{}},'b',{{}})
s =
a: {}
b: {}
Per inciso, qualsiasi il tempo che si desidera impostare un valore di campo a un array di celle utilizzando STRUCT richiede che si comprendono in un altro array di celle. Ad esempio, questo crea un unico elemento della struttura con i campi che contengono una matrice di celle e un vettore:
>> s = struct('strings',{{'hello','yes'}},'lengths',[5 3])
s =
strings: {'hello' 'yes'}
lengths: [5 3]
Ma questo crea un array di due elementi di struttura, distribuendo la matrice di celle ma replicante il vettore:
>> 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]
Altri suggerimenti
ARGH ... Credo di aver trovato la risposta. struct()
ha più comportamenti, tra cui:
Nota Se uno qualsiasi dei campi valori è un array cella vuota {}, il MATLAB software crea una struttura vuota matrice in cui tutti i campi sono anche vuota.
e apparentemente se si passa un membro di una struttura 0x0 come argomento, è come una specie di fantasma vuoto che in realtà non compare nella lista degli argomenti. (Che è ancora probabilmente un bug)
bug2.m:
function bug2(arg1, arg2)
disp(sprintf('number of arguments = %d\narg1 = ', nargin));
disp(arg1);
test case:
>> 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
Questo comportamento persiste nel 2008b, e in realtà non è proprio un bug (anche se non direi che i progettisti destinati per esso): Quando fate un passo in add_something (S, 'boing') e guardare il primo argomento (per esempio selezionandola e premendo F9), si otterrebbe alcuni di uscita relativa alla struttura vuota S. Passo in add_something (S.something, 'test') e guardare il primo argomento, e che ci si vede che è in realtà interpretato come 'prova'!
Lo struct.fieldname sintassi è progettato per restituire un oggetto di tipo 'elenco separato da virgole'. Le funzioni in MATLAB sono progettati per ricevere un oggetto di questo tipo esatto: i nomi degli argomenti sono indicati per i valori nella lista, nell'ordine in cui sono passati. Nel tuo caso, dal momento che il primo argomento è un elenco vuoto , il separato da virgole-list la funzione riceve inizia davvero al secondo valore si passa -. Vale a dire, 'test'
uscita è identica in 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