في جافا معزز للحلقة، هل هو آمن لتولي التعبير أن يحلق فوق سيتم تقييمها مرة واحدة فقط؟
سؤال
في جاوة، ومقابل كل حلقة.
إذا كان لدي الأسلوب الذي يولد مجموعة، ودعا genArray()
.
في التعليمة البرمجية التالية، فإن مجموعة في كل مرة يتم إعادة إنشاء، من خلال الدعوة genArray()
؟
أم أن الدعوة جافا مرة واحدة الطريقة وتخزين نسخة من مجموعة؟
for (String s : genArray())
{
//...
}
والشكر
المحلول
المعززة للبيان أ > والمواصفات لغة جافا كتب ما يلي:
<اقتباس فقرة>والمعززة للبيان له النموذج:
EnhancedForStatement:
for ( VariableModifiersopt Type Identifier: Expression) Statement
وهذا التعبير يجب أن يكون إما نوع
Iterable
وإلا فإنه يجب أن يكون ل
نوع مصفوفة (§10.1)، أو لمرة والترجمة
يحدث خطأ.
ونطاق متغير محلي أعلن
في الجزء FormalParameter ل
بيان تعزيز for
(§14.14) هو
البيان الوارد
ومعنى for
تعزيز
ويرد بيان الترجمة إلى
بيان for
الأساسي.
إذا نوع <م> Expression
م> هو
نوع فرعي من Iterable
، ثم ترك <م> I
م> يكون
نوع من التعبير
التعبير. م> iterator()
. البيان for
تعزيز ما يعادل
بيان for
الأساسي لل
النموذج:
for (I #i = Expression.iterator(); #i.hasNext(); ) {
VariableModifiersopt Type Identifier = #i.next();
Statement
}
وأين <م> #i
م> هو لدت مترجم،
المعرف الذي يختلف عن أي
معرفات أخرى (ولدت مترجم،
أو غير ذلك) التي هي في نطاق (§6.3)
في النقطة حيث معززة ل
يحدث بيان.
وإلا فإن التعبير بالضرورة
يحتوي على نوع مجموعة، <م> T[]
م>. السماح <م> L1 ... Lm
م>
يكون (ربما فارغة) تسلسل
التسميات التي تسبق مباشرة
بيان for
المعزز. ثم
وهذا يعني للمبادرة المعززة للبيان
وتعطى من قبل for
الأساسية التالية
بيان:
T[] a = Expression;
L1: L2: ... Lm:
for (int i = 0; i < a.length; i++) {
VariableModifiersopt Type Identifier = a[i];
Statement
}
وعندما يتم التحويل البرمجي إنشاء <م> من م> و <م> <ط / م> المعرفات التي تختلف عن أي معرفات أخرى (ولدت مترجم، أو غير ذلك) التي هي في نطاق في النقطة التي المعززة للبيان يحدث.
اقتباس فقرة> وحتى في قضيتك، genArray()
لا يرجع نوع فرعي من Iterable
لكن نوع مصفوفة، لذلك لديك بيان for
تعزيز ما يعادل بيان for
الأساسية التالية:
String[] a = genArray();
...
for (int i = 0; i < a.length; i++) {
String s = a[i];
// ...
}
وبالتالي سوف يتم استدعاؤها genArray()
مرة واحدة فقط (ولكن الجواب المقبول حاليا خاطئ جزئيا).
نصائح أخرى
وجافا استدعاء genArray () مرة واحدة، احصل على وجوه مكرر، ونسمي ذلك عدة مرات.
ووينبغي التعود مرة واحدة فقط - انها نفس الدعوة هذه:
String[] strings = genArray();
for (String s : strings) {
...