ماذا يطبع البرنامج التالي؟
package main
func main() {
var x = []string{"A", "B", "C"}
for i, s := range x {
print(i, s, ",")
x[i+1] = "M"
x = append(x, "Z")
x[i+1] = "Z"
}
}
الخيارات:
- 0A,1B,2C,
- 0A,1Z,2Z,
- 0A,1M,2M,
- 0A,1M,2C,
- 0A,1Z,2M,
- 0A,1M,2Z,
- (حلقة لا نهائية)
الإجابة: 0A,1M,2C,
شغّله على Go play.
النقاط الأساسية:
- التكرار بـ range على حاوية يمرّ على عناصر نسخة من الحاوية. ويحدث تقييم النسخة قبل تنفيذ الحلقة، لذا لا يتغير طول النسخة ولا سعتها أبداً.
- تشير الشريحة إلى عناصرها على مصفوفة أساسية. لذا فإن نسخة الشريحة تتشارك العناصر نفسها (والمصفوفة الأساسية نفسها) مع الشريحة.
- الإسناد
x[i+1] = "M"في خطوة الحلقة الأولى يعدّل العنصر الثاني في الشريحة الأوليةxوفي نسخة الشريحة الأوليةx. - إذا لم تكن خانات العناصر الزائدة في الشريحة المعطاة الأولى لاستدعاء
appendكافية لاستيعاب جميع العناصر الملحَقة، فسيُنشئ استدعاءappendمصفوفة أساسية جديدة لاستيعاب جميع عناصر الشريحة المعطاة الأولى والعناصر الملحَقة. لذا، في نهاية خطوة الحلقة الأولى، تتغير المصفوفة الأساسية للشريحةx. غير أن هذا التغيير لا يؤثر على نسخة الشريحة المستخدمة في تكرار العناصر. وتُطبَّق جميع تعديلات العناصر اللاحقة على المصفوفة الأساسية الجديدة، لذا ليس لها أي تأثير على النسخة المستخدمة في تكرار العناصر.
هذا الاختبار أعلاه مستمد من أحد اختبارات Valentin Deleplace. وفي ما يلي الاختبار الأصلي.
package main
func main() {
var x = []string{"A", "B", "C"}
for i, s := range x {
print(i, s, ",")
x = append(x, "Z")
x[i+1] = "Z"
}
}
يطبع الاختبار الأصلي 0A,1B,2C,، لأن الحاوية المكرَّر عليها هي نسخة من x الأولية، ولا تُعدَّل عناصر النسخة أبداً.
وفي ما يلي اختبار آخر وضعه Valentin Deleplace (مع تعديل طفيف).
package main
func main() {
var y = []string{"A", "B", "C", "D"}
var x = y[:3]
for i, s := range x {
print(i, s, ",")
x = append(x, "Z")
x[i+1] = "Z"
}
}
يطبع الاختبار الآخر 0A,1Z,2C,. وهو مشابه للاختبار الموسَّع أعلاه. النقاط الأساسية:
- استدعاء
appendالأول لا ينشئ مصفوفة أساسية جديدة، لذا فإن الإسنادx[i+1] = "Z"في الحلقة الأولى له تأثير على الشريحة الأوليةx(وعلى نسختها المستخدمة في تكرار العناصر). - استدعاء
appendالثاني ينشئ مصفوفة أساسية جديدة، لذا فإن إسناداتx[i+1] = "Z"اللاحقة ليس لها أي تأثير على الشريحة الأوليةx(وعلى نسختها المستخدمة في تكرار العناصر).