در Go، for range یک بلوک کد را برای مقادیر حاصل از یک عبارت بازه تکرار میکند. عبارت بازه تعیین میکند که هر تکرار یک مقدار تولید کند یا دو مقدار.
range روی یک اسلایس، اندیس و مقدار هر عنصر را به ترتیب تولید میکند:
vals := []int{10, 20, 30}
for i, v := range vals {
fmt.Println(i, v)
}
// 0 10
// 1 20
// 2 30
range روی یک مپ هر کلید و مقدار را تولید میکند، اما ترتیب تکرار تضمینشده نیست.
Go عمداً ترتیب تکرار مپ را تصادفی میکند، بنابراین یک برنامهٔ یکسان ممکن است در هر اجرا خروجی متفاوتی تولید کند.
hash := map[int]int{9: 10, 99: 20, 999: 30}
for k, v := range hash {
fmt.Println(k, v)
}
// 99 20
// 999 30
// 9 10
range روی یک رشته، اندیس بایت و هر رون (نقطهٔ کد یونیکد) را تولید میکند.
در مثال زیر، 子 سه بایت را اشغال میکند، بنابراین 猫 از اندیس بایت 3 شروع میشود، نه 1.
for i, r := range "子猫" {
fmt.Println(i, r, string(r))
}
// 0 23376 子
// 3 29483 猫
اگر بهجای آن به اندیسهای رون نیاز دارید، رشته را به یک اسلایس از رونها تبدیل کنید:
for i, r := range []rune("子猫") {
fmt.Println(i, r, string(r))
}
// 0 23376 子
// 1 29483 猫
range میتواند مستقیماً روی یک عدد صحیح تکرار کند و مقادیری را از 0 تا خود آن عدد، بدون خودش، تولید کند.
مقادیر صفر و منفی معتبرند اما هیچ تکراری تولید نمیکنند.
for n := range 3 {
fmt.Println(n)
}
// 0
// 1
// 2
range یک «تکرارگر» از نوع iter.Seq[V] یا iter.Seq2[K, V] را میپذیرد.
تکرارگر یک تابع است که دنبالهای از مقادیر را یکییکی تولید میکند.
سپس range میتواند از میان آن مقادیر عبور کند.
text := "The quick brown fox"
for word := range strings.FieldsSeq(text) {
fmt.Println(word)
}
// The
// quick
// brown
// fox
names := []string{"Alice", "Bob", "Vera"}
for i, v := range slices.All(names) {
fmt.Println(i, ":", v)
}
// 0 : Alice
// 1 : Bob
// 2 : Vera
در پایان، range میتواند مقادیری را که از طریق یک کانال فرستاده میشوند دریافت کند تا زمانی که آن کانال جای دیگری بسته شود.
کانالها در ادامهٔ سرفصلهای مسیر با جزئیات بیشتری پوشش داده میشوند.
اگر متغیری تعریف شود اما هرگز استفاده نشود، Go کامپایل نمیشود.
vals := []int{10, 20, 30}
for i, v := range vals {
fmt.Println(v)
}
// Go build failed: declared and not used: i
اگر فقط مقدار لازم باشد، اندیس یا کلید را به _ نسبت دهید تا نادیده گرفته شود.
vals := []int{10, 20, 30}
for _, v := range vals {
fmt.Println(v)
}
// 10
// 20
// 30
اگر فقط اندیس لازم باشد، آن را کاملاً حذف کنید:
vals := []int{10, 20, 30}
for i := range vals {
fmt.Println(i)
}
// 0
// 1
// 2
اگر نه اندیس و نه مقدار لازم نباشد، میتوان هر دو را حذف کرد:
vals := []int{10, 20, 30}
count := 0
for range vals {
count++
}
// count == 3