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 حرفي يحتوي على أي صفائف خلية فارغة؟

هل كانت مفيدة؟

المحلول

كما اكتشفت نفسك بالفعل، هذا ليس خطأ ولكن "ميزة". بمعنى آخر، هو السلوك الطبيعي لل بنية وظيفة. إذا قمت بتمرير صفائف خلية فارغة كقيم حقل إلى بنية، فهذا يفترض أنك تريد صفيف بنية فارغة مع أسماء الحقول المحددة.

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

s = 

0x0 struct array with fields:
    a
    b

لتمرير مجموعة خلية فارغة كقيمة حقل حقيقية، ستفعل ما يلي:

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

s = 

    a: {}
    b: {}

صدفة، أي الوقت الذي ترغب في تعيين قيمة حقل إلى صفيف خلية باستخدام الهيكل يتطلب أن تشملها في صفيف خلية أخرى. على سبيل المثال، ينشئ هذا عنصر بنية واحدة مع الحقول التي تحتوي على صفيف خلية ومتجه:

>> 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 كوسيطة، فهو مثل نوع من الوهمية الفارغة التي لا تظهر حقا في قائمة الوسائط. (هذا لا يزال على الأرجح خطأ)

bug2.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

يستمر هذا السلوك في عام 2008B، وهو في الواقع ليس حقا خطأ (على الرغم من أنني لن أقول المصممون مخصصون له): عند خطوة إلى Add_Something (S، Boing ") ومشاهدة الوسيطة الأولى (قل من خلال تحديد ذلك والضغط على F9)، كنت تحصل بعض الناتج المتعلق بالهيكل الفارغ S. خطوة إلى Add_Something - اختبار "اختبار") ومشاهدة الوسيطة الأولى، وسترى أنها في الواقع تفسر بأنها "اختبار"!

تم تصميم Syntax Form.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