علل ومشكلات

سطر التوجيه go 1.mn في ملف go.mod لا يعمل مع بعض إصدارات سلسلة أدوات Go لبعض ملفات مصدر Go التي تحتوي توجيهات التعليق //line ...

غيّر Go 1.22 دلالات حلقات for-range وحلقات for;; التقليدية. ولأن التغييرات الدلالية تُبدّل سلوك الشيفرة الموجودة المكتوبة وفق الدلالات السابقة، فإنها تكسر التوافق العكسي.

وفي حين أن سلوك حلقات for-range القديمة لا يكاد يتأثر، فإن بعض حلقات for;; التقليدية القديمة تُظهر سلوكيات غير متوقعة بسبب هذا الكسر.

لمنع الشيفرة القديمة من سوء العمل، تشترط Go 1.22 وما بعدها أن يكون كل ملف مصدر Go محدَّدًا بإصدار Go. وهناك طريقتان شائعتان للقيام بذلك.

الطريقة الأولى هي إضافة تعليق //go:build go1.mn في بداية ملف مصدر Go تمامًا. غير أن إصدارات معيّنة من سلسلة أدوات Go معروف عنها وجود أخطاء عند التعامل مع هذا التوجيه.

والطريقة الأخرى هي إضافة توجيه go 1.mn في ملف go.mod الخاص بالوحدة الحاوية لملف مصدر Go. وللأسف، تحتوي بعض إصدارات سلسلة أدوات Go أيضًا على أخطاء في طريقة معالجتها لهذا.

على سبيل المثال، اعتبر وحدة يحدد ملف go.mod فيها الإصدار 1.21. إذا صُرّفت تلك الوحدة باستخدام سلسلة أدوات Go 1.22.x أو 1.23.y، فسيطبع البرنامج 210 (السلوك الجديد) بدلًا من المتوقع 333 (السلوك القديم). وهذا يبيّن أن سلسلة الأدوات تفشل في احترام الإصدار المحدد في ملف go.mod.

go.mod


module main

go 1.21

main.go


//line main.go:1
package main

func main() {
	for i := 0; i < 3; i++ {
	    defer func() {
	        print(i)
	    }()
	}
}

تم تحديد الخطأ، المتتبَّع في https://github.com/golang/go/issues/77248، مع اقتراب إصدار Go 1.26. وبالتالي، فإن إصدارات سلسلة أدوات Go التالية متأثرة بهذا الخطأ بشكل دائم:

  • جميع إصدارات 1.22 و1.23.
  • جميع إصدارات 1.24 السابقة لـ 1.24.13.
  • جميع إصدارات 1.25 السابقة لـ 1.25.7.