Треки
/
Go
Go
/
Салабус
/
Ітерація з range
Іт

Ітерація з range у Go

1 вправа

Про концепцію Ітерація з range

У Go for range повторює блок коду для кожного значення з виразу range. Вираз range визначає, чи кожна ітерація даватиме одне значення чи два.

Вирази 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 по рядку тексту (англ. string) дає байтовий індекс і кожну руну (кодову точку Unicode). У наведеному нижче прикладі 子 займає три байти, тож 猫 починається з байтового індексу 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 може приймати значення, надіслані через канал, доки цей канал деінде не закриють. Канали докладніше розглядаються далі в силабусі track.

Пропуск індексу або значення

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
Редагувати через GitHub Посилання відкривається в новому вікні або вкладці

Вивчити концепцію Ітерація з range