غيّر Go 1.22 دلالات حلقات for-range وحلقات for;; التقليدية. ولأن التغييرات الدلالية تُبدّل سلوك الشيفرة الموجودة المكتوبة وفق الدلالات السابقة، فإنها تكسر التوافق العكسي.
وفي حين أن سلوك حلقات for-range القديمة لا يكاد يتأثر، فإن بعض حلقات for;; التقليدية القديمة تُظهر سلوكيات غير متوقعة بسبب هذا الكسر.
لكي نواصل استخدام الدلالات القديمة السابقة لـ Go 1.22 في عصر Go 1.22+، يجب علينا تحديد إصدار Go لكل ملف مصدر Go. وإحدى طرق تحقيق ذلك هي إضافة توجيه تعليق //go:build go1.21 في بداية ملف مصدر Go الذي يحتوي الشيفرة القديمة.
ورغم أنه موثّق رسميًا، فإن هذه الطريقة غير فعّالة حاليًا مع إصدارات سلسلة أدوات Go 1.22.x بسبب خطأ معروف.
وأصف هنا هذا الخطأ ببساطة: بالنسبة لملف مصدر Go غير محدَّد إصدار Go فيه في ملف go.mod، يفشل توجيه التعليق //go:build go1.mn الموجود فيه في تحديد إصدار Go له.
وهذا مثال:
main.go
//go:build go1.21
package main
import "fmt"
func filter(n int) bool {
return n&0xF == 0
}
// ابحث عن القيم وأعِدها دون إفساد الترتيب.
func search(start, end int) (r []int) {
var count = 0
for i, index := start, 0; i <= end; i++ {
if filter(i) {
count++
defer func(value int) {
r[index] = value
index++
}(i)
}
}
r = make([]int, count)
return
}
func main() {
fmt.Println(search(10, 36))
}
عند تشغيل ملف Go كسكربت بالأمر go run (دون وجود ملف go.mod معني)، يطبع البرنامج المثال [16 0] مع إصدارات سلسلة أدوات Go 1.22.x، لأن دلالات Go 1.22+ هي المستخدمة، وهذا خطأ. وينبغي أن يطبع [32 16]، كما هو الحال مع إصدارات سلسلة الأدوات الأقدم (1.21-) والأحدث (1.23+). [1]
$ gotv 1.21 run main.go
[Run]: $HOME/.cache/gotv/tag_go1.21.13/bin/go run main.go
[32 16]
$ gotv 1.22 run main.go
[Run]: $HOME/.cache/gotv/tag_go1.22.12/bin/go run main.go
[16 0]
$ gotv 1.23 run main.go
[Run]: $HOME/.cache/gotv/tag_go1.23.9/bin/go run main.go
[32 16]
رفض فريق Go الأساسي عن قصد إصلاح الخطأ في إصدارات 1.22.x. لذا ينبغي أن تكون على دراية بأن الخطأ سيبقى دائمًا في إصدارات 1.22.x عندما تستخدمها لتطوير مشاريع Go.
هناك طريقة أخرى لتحديد إصدارات Go لملفات مصدر Go. وتلك الطريقة أيضًا لا تعمل مع بعض إصدارات سلسلة أدوات Go.
- GoTV (https://go101.org/apps-and-libs/gotv.html) أداة تُستخدم لتثبيت إصدارات متعايشة من سلسلة أدوات Go واستخدامها بانسجام. ↩︎