غيّر Go 1.22 دلالات حلقات for، بما في ذلك حلقات for-range والحلقات التقليدية ذات الشروط الثلاثة for ..; ..; .. {...}. للتفاصيل، يرجى قراءة تغييرات دلالات حلقة for في Go 1.22: كن على دراية بالأثر.
في رأيي الصريح، الأثر الإجمالي للدلالات الجديدة لحلقات for-range إيجابي، بينما الأثر الإجمالي للدلالات الجديدة للحلقات التقليدية ذات الشروط الثلاثة for;; سلبي. ويعرض المقال المُشار إليه أعلاه جميع الآثار السيئة لتغيير دلالات الحلقات التقليدية ذات الشروط الثلاثة for;; التي وجدتها حتى الآن.
ومن الحقائق أن أحدث سلسلة أدوات Go الرسمية لا تنفّذ الدلالات الجديدة بشكل صحيح حاليًا في بعض الحالات التي تُستخدم فيها قيم strings.Builder كمتغيرات تكرار (معلنة حديثًا) في الحلقات التقليدية ذات الشروط الثلاثة for;;. ويوضّح المثال التالي إحدى هذه الحالات:
package main
import (
"fmt"
"strings"
)
func foo() string {
for b, i := (strings.Builder{}), byte('a'); ; i++ {
b.WriteByte(i) // لا يحدث panic
if i == 'z' {
return b.String()
}
}
}
func bar(callback func(*strings.Builder)) string {
for b, i := (strings.Builder{}), byte('a'); ; i++ {
b.WriteByte(i) // يحدث panic هنا
callback(&b)
if i == 'z' {
return b.String()
}
}
}
func main() {
fmt.Println(foo())
debugProcess := func(pb *strings.Builder) {
//fmt.Println(pb.String()) // لا يفعل شيئًا
}
fmt.Println(bar(debugProcess))
}
لا يحدث panic في البرنامج المثال أعلاه مع إصدارات سلسلة أدوات Go الرسمية السابقة لـ v1.22: [1]
$ gotv 1.21 run main.go
[Run]: $HOME/.cache/gotv/tag_go1.21.12/bin/go run main.go
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
لكن مع سلسلة أدوات Go الرسمية v1.22+، يحدث panic في البرنامج المثال:
$ gotv 1.22 run main.go
[Run]: $HOME/.cache/gotv/tag_go1.22.5/bin/go run main.go
abcdefghijklmnopqrstuvwxyz
panic: strings: illegal use of non-zero Builder copied by value
ينبغي أن يكون سلوك الدالتين foo وbar متسقًا إحداهما مع الأخرى، لكن سلسلة أدوات Go الرسمية v1.22+ تفشل في تحقيق هذا الضمان. في الواقع، وفق الدلالات الجديدة في Go 1.22+، ينبغي أن تنتج كل من الدالتين foo وbar حالة panic، لأن قيم nocopy لا ينبغي استخدامها كمتغيرات تكرار (معلنة حديثًا) منذ Go 1.22.
ملاحظة: فشل الأمر go vet الموفَّر في إصدارات سلسلة أدوات Go 1.22 و1.23 في التحذير من مثل هذه الحالات.
رفض فريق Go الأساسي إصلاح هذا الخطأ. ينبغي أن تكون على دراية بهذا الخطأ.
- GoTV (https://go101.org/apps-and-libs/gotv.html) أداة تُستخدم لتثبيت إصدارات متعايشة من سلسلة أدوات Go واستخدامها بانسجام. ↩︎