محتويات الدورة

Go / الأساسي: القيم وعقود البرامج / الدرس 4

المصفوفات والشرائح وحدود النص

تتبع الطول والسعة والتخزين الخلفي ووحدات النص بدلا من اعتبار كل متتالية نسخة مستقلة.

وقت القراءة التقريبي: 4 دقيقةتاريخ مراجعة المحتوى
في هذه الصفحة

أهداف الدرس

  • تمييز قيم المصفوفات من أوصاف الشرائح.
  • توقع المشاركة وسلوك append محدود السعة.
  • اختيار وحدات فهرسة واجتياز نص آمنة.

الشريحة تصف منظورا لمصفوفة

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

يضبط الطول الفهرسة الصالحة من صفر حتى len(s) ناقص واحد. تصف السعة مدى تمديد الشريحة بإعادة التقسيم من بدايتها الحالية؛ ولا تبيح الفهرسة بعد الطول. طول شريحة nil وسعتها صفر، وتدعم range وappend، وتختلف عن شريحة فارغة مضمونة عدم nil.

جعل الاستقلال صريحا

ينشئ البرنامج الأول منظورا يشارك base ثم نسخة عناصر مستقلة صريحة. يغير view[0] العنصر في base لأنه مشترك. ولا يغير independent[1] الشريحة view لأن الإلحاق بوجهة nil خصص تخزينا للقيم المنسوخة. لا تحمل عناصر int الثابتة حقولا مرجعية أخرى.

ليس نسخ العناصر السطحي نسخا عميقا متكررا. في [][]int أو بنى تحتوي خرائط قد يبقي نسخ العناصر الخارجية البيانات الداخلية مشتركة. وثق هل تعيد الدالة منظورا مستعارا أو بيانات مستقلة مملوكة، واختبر المشاركة التي يجوز للمستدعي الاعتماد عليها.

go منظور مشترك ونسخة مقصودة
package main

import "fmt"

func main() {
	base := []int{1, 2, 3}
	view := base[:2]
	view[0] = 9
	independent := append([]int(nil), view...)
	independent[1] = 8
	fmt.Println(base, view, independent)
}
الناتج المتوقع
[9 2 3] [9 2] [9 8]

يصل التغيير الأول إلى base؛ ولا يصل تعديل التخزين المستقل المنسوخ.

حفظ الشريحة المعادة

تعيد append شريحة محدثة. إذا كفت السعة فقد تعيد استخدام المصفوفة الخلفية؛ وإلا تخصص مصفوفة كافية وتنسخ العناصر السابقة. عامل النمو الدقيق اختيار تنفيذ، فلا تتوقع تسلسل سعات عالميا. احفظ القيمة المعادة دائما وأعد النظر في الأسماء البديلة عند تغير التخزين.

قد يكتب الإلحاق عبر اسم فوق عناصر يراها آخر عند مشاركة السعة الإضافية. يحد تعبير الشريحة الكامل s[low:high:max] السعة، فيمنع هذا الإلحاق من النمو داخل المنطقة الباقية المشتركة، لكنه لا يمنع الكتابة المباشرة للعناصر المشتركة أصلا.

إجبار append على التخصيص دون تخمين النمو

يقيد البرنامج التالي طول المنظور وسعته باثنين. يجب أن يخصص إلحاق قيمة ثالثة تخزينا خلفيا منفصلا، فلا يغير التعديل اللاحق في grown الشريحة base. هذه نتيجة حتمية لعقد السعة، لا ملاحظة لاستراتيجية نمو تنفيذ معين.

يفيد تقييد السعة عند إعادة منظور ينبغي ألا يلحق داخل عناصر المستدعي التالية. لكنه لا يجعله ثابتا ولا يثبت ملكية حصرية. إذا وجب عزل تعديل العناصر الحالية أيضا فانسخها. اختر أصغر وعد يفي بحاجة الواجهة الفعلية.

go منظور محدود السعة
package main

import "fmt"

func main() {
	base := []int{1, 2, 3}
	limited := base[:2:2]
	grown := append(limited, 7)
	grown[0] = 8
	fmt.Println(base, grown)
}
الناتج المتوقع
[1 2 3] [8 2 7]

ينشئ الإلحاق بعد السعة تخزينا مستقلا؛ ولا تُطبع سعته الدقيقة عمدا.

قيم range قيم وليست أسماء بديلة للعناصر

ينتج range على الشريحة فهارس ونسخ قيم العناصر. لا يبدل إسناد متغير القيمة عنصر الشريحة؛ استخدم s[i]. يُقيّم تعبير الاجتياز قبل التكرار حسب المواصفة، ولا يزيد عدد الدورات لمجرد الإلحاق بمتغير الشريحة داخل الحلقة. تجنب الاعتماد على آثار تعديل دقيقة.

في النص تعد len البايتات وتعيد الفهرسة بايتا ويفك range الرونات بمواضع بايتية. تستطيع شريحة بايتات تمثيل بيانات عامة وهي قابلة للتعديل. للتحويل بين []byte وstring دلالات قيم لغوية؛ ولا تستنتج إذن مشاركة قابلة للتعديل من تحسينات تخصيص داخلية محتملة.

الأخطاء الشائعة وإصلاحها

يؤثر تغيير عنصر في شريحة أخرى دون توقع.

لماذا يحدث؟
تشارك أوصاف الشرائح التخزين الخلفي.
كيف تصلحه؟
انسخ عندما تلزم عناصر مستقلة.
كيف تتجنب تكراره؟
وثق دلالة المنظور والنسخة.

تُستخدم السعة حدا للفهرسة.

لماذا يحدث؟
اختلطت السعة بالطول الحالي.
كيف تصلحه؟
استخدم i < len(s) قبل الفهرسة.
كيف تتجنب تكراره؟
اختبر الشرائح الفارغة والجزئية.

لا يغير تعديل قيمة range المتتالية.

لماذا يحدث؟
متغير الحلقة نسخة قيمة عنصر.
كيف تصلحه؟
أسند عبر الفهرس أو مؤشر مقصود.
كيف تتجنب تكراره؟
راجع النسخ للقيم الداخلية الحاملة للمراجع.

اختبر فهمك

1. طول شريحة اثنان وسعتها أربعة. هل تصح قراءة s[2] وإنشاء s[:3]؟

اعرض الحل المشروح

تقع s[2] خارج الطول فتسبب هلع فهرسة. وتصح إعادة التقسيم s[:3] لأن الحد ضمن السعة، فتنتج شريحة طولها ثلاثة. ينتمي العنصر المكشوف للمصفوفة الخلفية، ويعتمد معناه على التهيئة والأسماء البديلة. تسمح السعة بإعادة التقسيم لا الفهرسة المباشرة خارج الطول.

2. صمم دالة تعيد أول قيمتي int دون أن يؤثر تعديل النتيجة في المدخل.

اعرض الحل المشروح

افحص أن الطول اثنان على الأقل ثم خصص وجهة من عنصرين وانسخ القيمتين. أعد خطأ للمدخل الأقصر حسب العقد. لا يكفي تقييد السعة لأن result[0] سيبقى مشتركا. ولعناصر int يثبت نسخ العناصر الاستقلال المطلوب دون سياسة نسخ متكرر.

أهم ما تعلمته

  • يشارك نسخ الشريحة العناصر حتى يفصلها نسخ صريح أو إعادة تخصيص مناسبة.
  • يضبط الطول الفهرسة والسعة إعادة التقسيم وإعادة استخدام append.
  • يتطلب range ومعالجة النص اختيارات مقصودة للقيم والوحدات.

المراجع الرسمية