الوسائط المسماة اختيارية في الرياضيات
-
06-07-2019 - |
سؤال
ما هي أفضل طريقة / الكنسي لتعريف دالة مع الوسائط المسماة اختياري؟ لجعلها ملموسة، دعونا إنشاء foo
وظيفة مع الوسائط المسماة a
، b
، وc
، التي الافتراضية إلى 1، 2، و 3، على التوالي. وعلى سبيل المقارنة، وهنا نسخة من foo
بحجج الموضعية:
foo[a_:1, b_:2, c_:3] := bar[a,b,c]
وهنا يتم إدخال عينة والإخراج لإصدار الوسائط المسماة من foo
:
foo[] --> bar[1,2,3]
foo[b->7] --> bar[1,7,3]
foo[a->6, b->7, c->8] --> bar[6,7,8]
ووينبغي بالطبع أيضا أن يكون من السهل أن يكون الحجج الموضعية قبل الوسائط المسماة.
المحلول
ولقد وجدت طريقة قياسية للقيام بذلك في وثائق الرياضيات: HTTP: // المرجعية .wolfram.com / الرياضيات / تعليمي / SettingUpFunctionsWithOptionalArguments.html
Options[foo] = {a->1, b->2, c->3}; (* defaults *)
foo[OptionsPattern[]] := bar[OptionValue@a, OptionValue@b, OptionValue@c]
والكتابة "OptionValue" في كل مرة القليل مرهقة. لسبب ما لا يمكن جعل مجرد اختصار العالمي مثل ov = OptionValue
لكن يمكنك أن تفعل هذا:
foo[OptionsPattern[]] := Module[{ov},
ov[x___] := OptionValue[x];
bar[ov@a, ov@b, ov@c]]
وأو هذا:
With[{ov = OptionValue},
foo[OptionsPattern[]] := bar[ov@a, ov@b, ov@c]
]
وأو هذا:
$PreRead = ReplaceAll[#, "ov" -> "OptionValue"] &;
foo[OptionsPattern[]] := bar[ov@a, ov@b, ov@c]
نصائح أخرى
نعم، OptionValue
يمكن أن تكون صعبة بعض الشيء لأنه لا يعتمد على قطعة من السحر بحيث
وOptionValue[name]
ما يعادل OptionValue[f,name]
، حيث f
هو رئيس الجانب الأيسر للقاعدة التحول الذي يبدو OptionValue[name]
.
ورمي في Automatic
صريحة عادة لا حيلة، وذلك في قضيتك وأود أن أقول أن الحل هو:
Options[foo] = {a -> 1, b -> 2, c -> 3};
foo[OptionsPattern[]] :=
bar @@ (OptionValue[Automatic, #] &) /@ First /@ Options[foo]
وبالمناسبة، الخيارات المستخدمة ينبغي القيام به عن طريق مطابقة لopts:___?OptionQ
، ومن ثم إيجاد القيم الخيار يدويا كما {a,b,c}/.Flatten[{opts}]
. وOptionQ
الاختيار نمط لا يزال حوالي (وإن لم يكن موثقة)، ولكن النهج OptionValue
لديه ميزة أن تحصل تحذيرات من الخيارات غير موجودة (مثل foo[d->3]
). وهذا من شأنه أيضا أن تكون الحال بالنسبة لاستجابة الثانية، ولكن ليس لاحد كنت قد قبلته.
وأنا رمي هذا حل ممكن في هذا المزيج:
foo[opts___Rule] := Module[{f},
f@a = 1; (* defaults... *)
f@b = 2;
f@c = 3;
each[a_->v_, {opts}, f@a = v];
Return[bar[f@a, f@b, f@c]]
]
وأنا أحب ذلك لاختصارية ولكن لا اعتقد انها الطريقة القياسية. أي gotchas مع القيام به بهذه الطريقة؟
وPS، فإنه يستخدم وظيفة أداة يدوية التالية:
SetAttributes[each, HoldAll]; (* each[pattern, list, body] *)
each[pat_, lst_, bod_] := (* converts pattern to body for *)
Scan[Replace[#, pat:>bod]&, Evaluate@lst] (* each element of list. *)